Stanford Dogs

In [1]:
!pip install matplotlib
!pip install keras-tuner
!pip install seaborn
Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/site-packages (3.5.1)
Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/site-packages (from matplotlib) (1.3.2)
Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.7/site-packages (from matplotlib) (2.8.2)
Requirement already satisfied: numpy>=1.17 in /usr/local/lib/python3.7/site-packages (from matplotlib) (1.18.5)
Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.7/site-packages (from matplotlib) (8.2.0)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.7/site-packages (from matplotlib) (4.28.5)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/site-packages (from matplotlib) (0.11.0)
Requirement already satisfied: pyparsing>=2.2.1 in /usr/local/lib/python3.7/site-packages (from matplotlib) (2.4.7)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.7/site-packages (from matplotlib) (20.9)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.1.1; however, version 21.3.1 is available.
You should consider upgrading via the '/usr/local/bin/python3.7 -m pip install --upgrade pip' command.
Requirement already satisfied: keras-tuner in /usr/local/lib/python3.7/site-packages (1.1.0)
Requirement already satisfied: requests in /usr/local/lib/python3.7/site-packages (from keras-tuner) (2.24.0)
Requirement already satisfied: packaging in /usr/local/lib/python3.7/site-packages (from keras-tuner) (20.9)
Requirement already satisfied: scipy in /usr/local/lib/python3.7/site-packages (from keras-tuner) (1.5.2)
Requirement already satisfied: ipython in /usr/local/lib/python3.7/site-packages (from keras-tuner) (7.16.1)
Requirement already satisfied: tensorboard in /usr/local/lib/python3.7/site-packages (from keras-tuner) (2.5.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.7/site-packages (from keras-tuner) (1.18.5)
Requirement already satisfied: kt-legacy in /usr/local/lib/python3.7/site-packages (from keras-tuner) (1.0.4)
Requirement already satisfied: backcall in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (0.2.0)
Requirement already satisfied: pickleshare in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (0.7.5)
Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (3.0.22)
Requirement already satisfied: setuptools>=18.5 in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (59.3.0)
Requirement already satisfied: jedi>=0.10 in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (0.18.1)
Requirement already satisfied: pexpect in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (4.8.0)
Requirement already satisfied: decorator in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (5.1.0)
Requirement already satisfied: pygments in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (2.10.0)
Requirement already satisfied: traitlets>=4.2 in /usr/local/lib/python3.7/site-packages (from ipython->keras-tuner) (4.3.3)
Requirement already satisfied: parso<0.9.0,>=0.8.0 in /usr/local/lib/python3.7/site-packages (from jedi>=0.10->ipython->keras-tuner) (0.8.2)
Requirement already satisfied: wcwidth in /usr/local/lib/python3.7/site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython->keras-tuner) (0.2.5)
Requirement already satisfied: six in /usr/local/lib/python3.7/site-packages (from traitlets>=4.2->ipython->keras-tuner) (1.16.0)
Requirement already satisfied: ipython-genutils in /usr/local/lib/python3.7/site-packages (from traitlets>=4.2->ipython->keras-tuner) (0.2.0)
Requirement already satisfied: pyparsing>=2.0.2 in /usr/local/lib/python3.7/site-packages (from packaging->keras-tuner) (2.4.7)
Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.7/site-packages (from pexpect->ipython->keras-tuner) (0.7.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/site-packages (from requests->keras-tuner) (2020.12.5)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/site-packages (from requests->keras-tuner) (1.25.11)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/site-packages (from requests->keras-tuner) (2.10)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/site-packages (from requests->keras-tuner) (3.0.4)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (3.3.4)
Requirement already satisfied: grpcio>=1.24.3 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (1.37.1)
Requirement already satisfied: wheel>=0.26 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (0.36.2)
Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (0.6.0)
Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (1.0.1)
Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (0.10.0)
Requirement already satisfied: google-auth<2,>=1.6.3 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (1.30.0)
Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (0.4.4)
Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (1.8.0)
Requirement already satisfied: protobuf>=3.6.0 in /usr/local/lib/python3.7/site-packages (from tensorboard->keras-tuner) (3.15.8)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/site-packages (from google-auth<2,>=1.6.3->tensorboard->keras-tuner) (0.2.8)
Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/site-packages (from google-auth<2,>=1.6.3->tensorboard->keras-tuner) (4.2.2)
Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/site-packages (from google-auth<2,>=1.6.3->tensorboard->keras-tuner) (4.7.2)
Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/site-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard->keras-tuner) (1.3.0)
Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/site-packages (from markdown>=2.6.8->tensorboard->keras-tuner) (4.0.1)
Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/site-packages (from pyasn1-modules>=0.2.1->google-auth<2,>=1.6.3->tensorboard->keras-tuner) (0.4.8)
Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/site-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard->keras-tuner) (3.1.0)
Requirement already satisfied: typing-extensions>=3.6.4 in /usr/local/lib/python3.7/site-packages (from importlib-metadata->markdown>=2.6.8->tensorboard->keras-tuner) (3.7.4.3)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/site-packages (from importlib-metadata->markdown>=2.6.8->tensorboard->keras-tuner) (3.4.1)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.1.1; however, version 21.3.1 is available.
You should consider upgrading via the '/usr/local/bin/python3.7 -m pip install --upgrade pip' command.
Requirement already satisfied: seaborn in /usr/local/lib/python3.7/site-packages (0.11.2)
Requirement already satisfied: scipy>=1.0 in /usr/local/lib/python3.7/site-packages (from seaborn) (1.5.2)
Requirement already satisfied: pandas>=0.23 in /usr/local/lib/python3.7/site-packages (from seaborn) (1.1.0)
Requirement already satisfied: matplotlib>=2.2 in /usr/local/lib/python3.7/site-packages (from seaborn) (3.5.1)
Requirement already satisfied: numpy>=1.15 in /usr/local/lib/python3.7/site-packages (from seaborn) (1.18.5)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.7/site-packages (from matplotlib>=2.2->seaborn) (4.28.5)
Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.7/site-packages (from matplotlib>=2.2->seaborn) (2.8.2)
Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/site-packages (from matplotlib>=2.2->seaborn) (1.3.2)
Requirement already satisfied: pyparsing>=2.2.1 in /usr/local/lib/python3.7/site-packages (from matplotlib>=2.2->seaborn) (2.4.7)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/site-packages (from matplotlib>=2.2->seaborn) (0.11.0)
Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.7/site-packages (from matplotlib>=2.2->seaborn) (8.2.0)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.7/site-packages (from matplotlib>=2.2->seaborn) (20.9)
Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/site-packages (from pandas>=0.23->seaborn) (2021.1)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/site-packages (from python-dateutil>=2.7->matplotlib>=2.2->seaborn) (1.16.0)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.1.1; however, version 21.3.1 is available.
You should consider upgrading via the '/usr/local/bin/python3.7 -m pip install --upgrade pip' command.
In [2]:
from stanford_dogs_utils import *
import numpy as np
import pandas as pd
import seaborn as sns
import os
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import tensorflow as tf
import cv2 as cv
from tensorflow.keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import timeit
import os
import pickle

from sklearn.metrics import classification_report, confusion_matrix
import keras_tuner as kt
from tensorflow.keras.models import load_model
In [3]:
gpu_info = !nvidia-smi
gpu_info = '\n'.join(gpu_info)
if gpu_info.find('failed') >= 0:
  print('Not connected to a GPU')
else:
  print(gpu_info)
Mon Jan  3 14:35:30 2022       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.57.02    Driver Version: 470.57.02    CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla T4            Off  | 00000000:00:1E.0 Off |                    0 |
| N/A   38C    P0    27W /  70W |      0MiB / 15109MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

Images preprocessing

Quick overview of data

In [4]:
annotations_dir = './annotation/Annotation/'
images_dir = './images/Images'
In [5]:
# Define path to data
#annotations_dir = './Dogs/Annotation' 
#images_dir = './Dogs/Images'
In [6]:
# Count the number of classes (dogs breeds)
breed_list = os.listdir(images_dir)
print("Number of breeds in dataset:", (len(breed_list)))
Number of breeds in dataset: 120
In [7]:
# Count number of pictures for each breed
df_breeds = pd.DataFrame(
    index=[breed.split('-',1)[1]
           for breed in breed_list],
    data=[len(os.listdir(images_dir + "/" + name))
          for name in breed_list],
    columns=["num_pictures"])

# Plot results
fig, ax = plt.subplots(1, 1, figsize=(15,8))
df_breeds.plot(kind="bar",
               legend=False,
               ax=ax)
ax.axhline(df_breeds["num_pictures"].mean(),
           color='r', alpha=.7,
           linestyle='--',
           label="Mean of pictures")
plt.title("Number of pictures for each "\
          "dogs breeds of Dataset",
          color="#343434", fontsize=22)
plt.legend()
plt.show()
In [8]:
for i in np.random.randint(0, len(breed_list), size=3):
    show_images_classes(images_dir, breed_list[i], 5)

One good practice over here is to start resizing our pictures as it will make the job of NN models easier

Pictures resizing

In [9]:
# Define test image
img_test = (images_dir 
            + "/" 
            + "n02096585-Boston_bull/n02096585_2809.jpg")
img_test = cv.imread(img_test)
In [10]:
# setting dim of the resize
height = 299
width = 299
dim = (width, height)
# resize image with OpenCV
res_img = cv.resize(img_test, dim, interpolation=cv.INTER_LINEAR)

# Show both img
fig = plt.figure(figsize=(16,6))
plt.subplot(1, 2, 1)
plt.imshow(img_test)
plt.title("Original shape : {}".format(img_test.shape))
plt.subplot(1, 2, 2)
plt.imshow(res_img)
plt.title("Resized shape : {}".format(res_img.shape))
plt.suptitle("Resizing image",
             color="black", 
             fontsize=22, y=.98)
plt.show()

Changing histograms of pictures

In [11]:
# Transform image with differents color sets
img_RGB = cv.cvtColor(img_test, cv.COLOR_BGR2RGB)
img_grayscale = cv.cvtColor(img_test, cv.COLOR_RGB2GRAY)
img_YUV = cv.cvtColor(img_test,cv.COLOR_BGR2YUV)
In [12]:
plot_histogram(["RGB", img_RGB], ["YUV", img_YUV])

We can see from the chart on the right that the light is accumulated on the center of the picture, hence we need to compensate for that.

Equalizing

In [13]:
# Equalization
img_YUV[:,:,0] = cv.equalizeHist(img_YUV[:,:,0])
img_equ = cv.cvtColor(img_YUV, cv.COLOR_YUV2RGB)
plot_histogram(["RGB", img_RGB], ["Equalized", img_equ])

Non Local means filter

In [14]:
# Apply non-local means filter on test img
dst_img = cv.fastNlMeansDenoisingColored(
    src=img_equ,
    dst=None,
    h=10,
    hColor=10,
    templateWindowSize=7,
    searchWindowSize=21)

# Show both img
fig = plt.figure(figsize=(16,6))
plt.subplot(1, 2, 1)
plt.imshow(img_equ)
plt.title("Original Image")
plt.subplot(1, 2, 2)
plt.imshow(dst_img)
plt.title("Filtered Image")
plt.suptitle("Non-local Means Filter",
             color="black", 
             fontsize=22, y=.98)
plt.show()

Data Augmentation

In [15]:
#Initilize Data Generator Keras
augmented_datagen = ImageDataGenerator(
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest')

# Convert test img to array
x = image.img_to_array(img_test)
x = x.reshape((1,) + x.shape)

i=0
fig = plt.figure(figsize=(16,12))
for batch in augmented_datagen.flow(x, batch_size=1):
    ax = fig.add_subplot(3,4,i+1)
    ax.imshow(image.array_to_img(batch[0]))
    i += 1
    if i % 12 == 0:
        break

plt.suptitle("Data Augmentation with Keras",
             color="black", 
             fontsize=22, y=.90)
plt.show()
In [16]:
custom_breed_list = [
    'n02096294-Australian_terrier',
    'n02093256-Staffordshire_bullterrier',
    'n02105505-komondor',
    'n02107142-Doberman',
    'n02086240-Shih-Tzu',
    'n02111500-Great_Pyrenees',
    'n02108915-French_bulldog',
    'n02100735-English_setter',
    'n02102318-cocker_spaniel',
    'n02108915-French_bulldog',
    'n02111129-Leonberg',
    'n02106662-German_shepherd',
    'n02110185-Siberian_husky',
    'n02101006-Gordon_setter',
    'n02109961-Eskimo_dog',
    'n02088094-Afghan_hound',
    'n02106166-Border_collie',
    'n02106550-Rottweiler',
    'n02108422-bull_mastiff',
    'n02107574-Greater_Swiss_Mountain_dog',
]
#20 dog races selected in this project
In [17]:
# Define numbers of breeds to preprocess
num_breeds = len(custom_breed_list) 

# Execute preprocessor on selection
start_time = timeit.default_timer()
# X = images
# y = labels
X, y = preprocessing_cnn(custom_breed_list, 299, 299)
# Convert in numpy array
X = np.array(X)
y = np.array(y)
preprocess_time = timeit.default_timer() - start_time
print("-" * 50)
print("Execution time for preprocessing :")
print("-" * 50)
print("Number of images preprocessed : {}"\
     .format(len(y)))
print("Shape of images np.array : {}"\
     .format(X.shape))
print("Total time : {:.2f}s".format(preprocess_time))
--------------------------------------------------
Execution time for preprocessing :
--------------------------------------------------
Number of images preprocessed : 3442
Shape of images np.array : (3442, 299, 299, 3)
Total time : 856.73s
In [18]:
# Show exemple preprocessed image
plt.imshow(image.array_to_img(X[10]));

Construction d'un CNN fait maison

In [19]:
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split

Preparing the data for the model

In [20]:
# The goal of the code below is to change the order of the data to avoid any abnormal patterns
# Using np.shuffle
img_space = np.arange(X.shape[0])
np.random.seed(8)
# Shuffle the space
np.random.shuffle(img_space)
# Apply to X and y in same order
X = X[img_space]
y = y[img_space]
In [21]:
# Change X type 
X = X.astype(np.float32)
# Encode y text data in numeric
encoder = LabelEncoder()
encoder.fit(y)
y = encoder.transform(y)
In [22]:
with open("./encoder.pickle", "wb") as f: 
    pickle.dump(encoder, f)
In [23]:
# Checking encoder created classes
print(encoder.classes_)
['Afghan_hound' 'Australian_terrier' 'Border_collie' 'Doberman'
 'English_setter' 'Eskimo_dog' 'French_bulldog' 'German_shepherd'
 'Gordon_setter' 'Great_Pyrenees' 'Greater_Swiss_Mountain_dog' 'Leonberg'
 'Rottweiler' 'Shih' 'Siberian_husky' 'Staffordshire_bullterrier'
 'bull_mastiff' 'cocker_spaniel' 'komondor']
In [24]:
### Create train and test set
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42)

print("-" * 50)
print("Size of created sets :")
print("-" * 50)
print("Train set size = ",x_train.shape[0])
print("Test set size = ",x_test.shape[0])
--------------------------------------------------
Size of created sets :
--------------------------------------------------
Train set size =  2753
Test set size =  689

This is the last step of of the data prep. We will use Keras ImageDataGenerator to create batches of images to work with. These will include Data Augmentation steps.

In [25]:
# Data generator on train set with Data Augmentation
# Validation set is define here
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest',
    validation_split=0.2)

#For validation and test, just rescale
test_datagen = ImageDataGenerator(rescale=1./255)

Construction du modèle CNN

In [26]:
from tensorflow.keras.models import Model
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import GlobalAveragePooling2D
from tensorflow.keras.layers import MaxPooling2D
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import Activation
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import plot_model
from tensorflow.keras import regularizers

from tensorflow.keras import backend as K

We are going to use major layers to build our CNN from scratch:

Convolution Layer: It's goal is to find features in images receinved in input

Pooling layers: Its goal is to reduce dimension while preserving main features

Correction Layer (ReLU): Replaces negative values with 0s. It is an activation layers

Dense layers: Takes a vector in input and returns another vector after applying a linear function, and eventually an activation function

Dropout: This is a regularization method, i.e. it's goal is to prevent overfitting. It does reset some proportion of weights to 0.

In the code below, we implement the CNN using a micture of VGG-16 and AlexNet as source of inspiration. Note the follwing

  • We decide to keep (4,4) as stride, as changing it does not affect much performance of our model
  • We decide to start with bigger filters (7,7) then gradually decrease size to (3,3) on last convolution layer to take into account the reduction of the dimension of our inputs
In [27]:
K.clear_session()

def custom_cnn_builder():
    """
    Raison d'être: Our builder function for our homemade CNN
    
    Args:
        None
    Retuns:
        The Newly built model
    """
    #First Convolution Layer
    inputs = Input(shape=(299,299,3))
    custom_CNN = Conv2D(filters=16,
                     kernel_size=(7,7), 
                     padding='same',
                     use_bias=False)(inputs)
    custom_CNN = BatchNormalization(axis=3, scale=False)(custom_CNN)
    custom_CNN = Activation('relu')(custom_CNN)
    custom_CNN = MaxPooling2D(pool_size=(4, 4),
                           strides=(4, 4),
                           padding='same')(custom_CNN)
    custom_CNN = Dropout(0.5)(custom_CNN)

    #Second Convolution Layer
    custom_CNN = Conv2D(filters=32,
                     kernel_size=(5,5), 
                     padding='same',
                     use_bias=False)(custom_CNN)
    custom_CNN = BatchNormalization(axis=3, scale=False)(custom_CNN)
    custom_CNN = Activation('relu')(custom_CNN)
    custom_CNN = MaxPooling2D(pool_size=(4, 4),
                           strides=(4, 4),
                           padding='same')(custom_CNN)
    custom_CNN = Dropout(0.5)(custom_CNN)

    #Third Convolution Layer
    custom_CNN = Conv2D(filters=64,
                     kernel_size=(3,3), 
                     padding='same',
                     use_bias=False)(custom_CNN)
    custom_CNN = BatchNormalization(axis=3, scale=False)(custom_CNN)
    custom_CNN = Activation('relu')(custom_CNN)
    custom_CNN = GlobalAveragePooling2D()(custom_CNN)

    #Fully Connected layer
    custom_CNN = Dense(128,activation='relu')(custom_CNN)
    custom_CNN = Dense(num_breeds, activation='softmax')(custom_CNN)

    my_custom_CNN = Model(inputs=inputs,
                           outputs=custom_CNN)
    
    return my_custom_CNN
In [28]:
custom_CNN = custom_cnn_builder()
[2022-01-03 14:50:00.391 tensorflow-2-3-gpu--ml-g4dn-xlarge-857ba94c8ff520cf618cce107153:280 INFO utils.py:27] RULE_JOB_STOP_SIGNAL_FILENAME: None
[2022-01-03 14:50:00.444 tensorflow-2-3-gpu--ml-g4dn-xlarge-857ba94c8ff520cf618cce107153:280 INFO profiler_config_parser.py:102] Unable to find config at /opt/ml/input/config/profilerconfig.json. Profiler is disabled.
In [29]:
custom_CNN.summary()
Model: "functional_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 299, 299, 3)]     0         
_________________________________________________________________
conv2d (Conv2D)              (None, 299, 299, 16)      2352      
_________________________________________________________________
batch_normalization (BatchNo (None, 299, 299, 16)      48        
_________________________________________________________________
activation (Activation)      (None, 299, 299, 16)      0         
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 75, 75, 16)        0         
_________________________________________________________________
dropout (Dropout)            (None, 75, 75, 16)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 75, 75, 32)        12800     
_________________________________________________________________
batch_normalization_1 (Batch (None, 75, 75, 32)        96        
_________________________________________________________________
activation_1 (Activation)    (None, 75, 75, 32)        0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 19, 19, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 19, 19, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 19, 19, 64)        18432     
_________________________________________________________________
batch_normalization_2 (Batch (None, 19, 19, 64)        192       
_________________________________________________________________
activation_2 (Activation)    (None, 19, 19, 64)        0         
_________________________________________________________________
global_average_pooling2d (Gl (None, 64)                0         
_________________________________________________________________
dense (Dense)                (None, 128)               8320      
_________________________________________________________________
dense_1 (Dense)              (None, 20)                2580      
=================================================================
Total params: 44,820
Trainable params: 44,596
Non-trainable params: 224
_________________________________________________________________
In [30]:
# Compile the CNN Model
custom_CNN.compile(optimizer="adam",
              loss="sparse_categorical_crossentropy",
              metrics=["accuracy", f1])
In [31]:
BATCH_SIZE = 16
EPOCHS = 30
In [32]:
history = custom_CNN.fit(
    train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='training'),
    validation_data=train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='validation'),
    steps_per_epoch=int(np.ceil(x_train.shape[0] / (2*BATCH_SIZE))),
    epochs=EPOCHS+20,
    verbose=2)
Epoch 1/50
87/87 - 29s - loss: 2.9180 - accuracy: 0.1168 - f1: 15.9228 - val_loss: 2.9760 - val_accuracy: 0.0782 - val_f1: 15.8494
Epoch 2/50
87/87 - 29s - loss: 2.8749 - accuracy: 0.1149 - f1: 15.4685 - val_loss: 3.0293 - val_accuracy: 0.0891 - val_f1: 13.2130
Epoch 3/50
87/87 - 28s - loss: 2.8359 - accuracy: 0.1348 - f1: 14.4949 - val_loss: 3.1498 - val_accuracy: 0.0800 - val_f1: 11.4337
Epoch 4/50
87/87 - 29s - loss: 2.8403 - accuracy: 0.1451 - f1: 15.0681 - val_loss: 2.9210 - val_accuracy: 0.0964 - val_f1: 15.7338
Epoch 5/50
87/87 - 29s - loss: 2.8333 - accuracy: 0.1327 - f1: 15.2540 - val_loss: 2.9061 - val_accuracy: 0.1164 - val_f1: 14.2118
Epoch 6/50
87/87 - 29s - loss: 2.8023 - accuracy: 0.1370 - f1: 15.0924 - val_loss: 3.1549 - val_accuracy: 0.0982 - val_f1: 12.3099
Epoch 7/50
87/87 - 29s - loss: 2.8100 - accuracy: 0.1377 - f1: 14.7139 - val_loss: 2.9725 - val_accuracy: 0.0836 - val_f1: 13.4861
Epoch 8/50
87/87 - 28s - loss: 2.7830 - accuracy: 0.1401 - f1: 14.5489 - val_loss: 3.0125 - val_accuracy: 0.1055 - val_f1: 12.9902
Epoch 9/50
87/87 - 28s - loss: 2.7536 - accuracy: 0.1593 - f1: 13.9045 - val_loss: 2.9502 - val_accuracy: 0.1291 - val_f1: 12.8304
Epoch 10/50
87/87 - 28s - loss: 2.7634 - accuracy: 0.1615 - f1: 13.5177 - val_loss: 2.9688 - val_accuracy: 0.1036 - val_f1: 12.6217
Epoch 11/50
87/87 - 29s - loss: 2.7296 - accuracy: 0.1514 - f1: 14.0476 - val_loss: 2.9007 - val_accuracy: 0.1109 - val_f1: 12.9828
Epoch 12/50
87/87 - 29s - loss: 2.7275 - accuracy: 0.1430 - f1: 14.2578 - val_loss: 2.8795 - val_accuracy: 0.1436 - val_f1: 13.2470
Epoch 13/50
87/87 - 28s - loss: 2.7001 - accuracy: 0.1651 - f1: 13.2680 - val_loss: 3.1431 - val_accuracy: 0.0927 - val_f1: 11.4857
Epoch 14/50
87/87 - 28s - loss: 2.6782 - accuracy: 0.1730 - f1: 13.2907 - val_loss: 3.7255 - val_accuracy: 0.0873 - val_f1: 10.9222
Epoch 15/50
87/87 - 29s - loss: 2.6776 - accuracy: 0.1665 - f1: 13.2006 - val_loss: 3.0937 - val_accuracy: 0.1145 - val_f1: 12.2863
Epoch 16/50
87/87 - 28s - loss: 2.6824 - accuracy: 0.1896 - f1: 13.3646 - val_loss: 2.7860 - val_accuracy: 0.1382 - val_f1: 12.4891
Epoch 17/50
87/87 - 28s - loss: 2.6866 - accuracy: 0.1839 - f1: 13.4011 - val_loss: 3.1899 - val_accuracy: 0.0945 - val_f1: 11.5200
Epoch 18/50
87/87 - 28s - loss: 2.6465 - accuracy: 0.1766 - f1: 12.8672 - val_loss: 3.1388 - val_accuracy: 0.1109 - val_f1: 11.9150
Epoch 19/50
87/87 - 28s - loss: 2.6544 - accuracy: 0.1788 - f1: 13.0381 - val_loss: 3.0237 - val_accuracy: 0.1200 - val_f1: 11.7845
Epoch 20/50
87/87 - 28s - loss: 2.6422 - accuracy: 0.1817 - f1: 13.0389 - val_loss: 2.8882 - val_accuracy: 0.1109 - val_f1: 13.0383
Epoch 21/50
87/87 - 28s - loss: 2.6355 - accuracy: 0.1846 - f1: 13.3247 - val_loss: 3.3054 - val_accuracy: 0.0782 - val_f1: 11.4781
Epoch 22/50
87/87 - 28s - loss: 2.6003 - accuracy: 0.2011 - f1: 12.7333 - val_loss: 3.0542 - val_accuracy: 0.1291 - val_f1: 11.6461
Epoch 23/50
87/87 - 28s - loss: 2.5949 - accuracy: 0.2040 - f1: 12.5274 - val_loss: 3.3516 - val_accuracy: 0.0855 - val_f1: 9.3189
Epoch 24/50
87/87 - 28s - loss: 2.6085 - accuracy: 0.2011 - f1: 12.8322 - val_loss: 2.9188 - val_accuracy: 0.1018 - val_f1: 11.9860
Epoch 25/50
87/87 - 28s - loss: 2.5986 - accuracy: 0.2055 - f1: 12.4979 - val_loss: 3.3896 - val_accuracy: 0.0709 - val_f1: 10.8607
Epoch 26/50
87/87 - 28s - loss: 2.5711 - accuracy: 0.2048 - f1: 12.4338 - val_loss: 2.7187 - val_accuracy: 0.1673 - val_f1: 12.6179
Epoch 27/50
87/87 - 29s - loss: 2.5773 - accuracy: 0.2048 - f1: 12.3437 - val_loss: 3.1998 - val_accuracy: 0.0964 - val_f1: 11.1063
Epoch 28/50
87/87 - 29s - loss: 2.5740 - accuracy: 0.2040 - f1: 12.4471 - val_loss: 3.2424 - val_accuracy: 0.0891 - val_f1: 11.5597
Epoch 29/50
87/87 - 28s - loss: 2.5836 - accuracy: 0.1889 - f1: 12.3688 - val_loss: 3.7008 - val_accuracy: 0.0945 - val_f1: 10.5216
Epoch 30/50
87/87 - 28s - loss: 2.5558 - accuracy: 0.2112 - f1: 12.3739 - val_loss: 3.3895 - val_accuracy: 0.0873 - val_f1: 11.1708
Epoch 31/50
87/87 - 28s - loss: 2.5352 - accuracy: 0.2141 - f1: 12.3673 - val_loss: 3.3150 - val_accuracy: 0.0982 - val_f1: 11.0932
Epoch 32/50
87/87 - 28s - loss: 2.5354 - accuracy: 0.2120 - f1: 11.8929 - val_loss: 2.9108 - val_accuracy: 0.1309 - val_f1: 11.2466
Epoch 33/50
87/87 - 29s - loss: 2.5502 - accuracy: 0.2069 - f1: 12.2783 - val_loss: 3.0623 - val_accuracy: 0.1200 - val_f1: 11.6771
Epoch 34/50
87/87 - 29s - loss: 2.5247 - accuracy: 0.2163 - f1: 12.5012 - val_loss: 2.9810 - val_accuracy: 0.0927 - val_f1: 11.6055
Epoch 35/50
87/87 - 28s - loss: 2.4983 - accuracy: 0.2221 - f1: 12.2891 - val_loss: 2.9129 - val_accuracy: 0.1218 - val_f1: 11.1990
Epoch 36/50
87/87 - 28s - loss: 2.5037 - accuracy: 0.2228 - f1: 11.9621 - val_loss: 2.9989 - val_accuracy: 0.1218 - val_f1: 11.0806
Epoch 37/50
87/87 - 28s - loss: 2.5001 - accuracy: 0.2228 - f1: 12.1486 - val_loss: 3.3412 - val_accuracy: 0.0982 - val_f1: 10.8866
Epoch 38/50
87/87 - 28s - loss: 2.4826 - accuracy: 0.2263 - f1: 12.0548 - val_loss: 3.3379 - val_accuracy: 0.0855 - val_f1: 9.1363
Epoch 39/50
87/87 - 28s - loss: 2.4710 - accuracy: 0.2228 - f1: 11.7339 - val_loss: 3.6930 - val_accuracy: 0.0782 - val_f1: 9.1139
Epoch 40/50
87/87 - 29s - loss: 2.4663 - accuracy: 0.2336 - f1: 12.1953 - val_loss: 2.9138 - val_accuracy: 0.1327 - val_f1: 10.9226
Epoch 41/50
87/87 - 28s - loss: 2.4802 - accuracy: 0.2379 - f1: 11.3444 - val_loss: 3.4950 - val_accuracy: 0.0909 - val_f1: 7.7442
Epoch 42/50
87/87 - 29s - loss: 2.4575 - accuracy: 0.2299 - f1: 11.6178 - val_loss: 2.9442 - val_accuracy: 0.1364 - val_f1: 11.8250
Epoch 43/50
87/87 - 28s - loss: 2.4508 - accuracy: 0.2343 - f1: 11.4980 - val_loss: 3.0556 - val_accuracy: 0.1382 - val_f1: 11.0854
Epoch 44/50
87/87 - 29s - loss: 2.4524 - accuracy: 0.2392 - f1: 11.5966 - val_loss: 2.9445 - val_accuracy: 0.1055 - val_f1: 9.5643
Epoch 45/50
87/87 - 28s - loss: 2.4852 - accuracy: 0.2487 - f1: 11.3917 - val_loss: 2.6733 - val_accuracy: 0.1291 - val_f1: 11.1893
Epoch 46/50
87/87 - 29s - loss: 2.4863 - accuracy: 0.2249 - f1: 11.9348 - val_loss: 3.2800 - val_accuracy: 0.0982 - val_f1: 10.1308
Epoch 47/50
87/87 - 28s - loss: 2.4106 - accuracy: 0.2523 - f1: 11.3295 - val_loss: 2.7049 - val_accuracy: 0.2018 - val_f1: 11.2273
Epoch 48/50
87/87 - 28s - loss: 2.4687 - accuracy: 0.2249 - f1: 11.4535 - val_loss: 3.0397 - val_accuracy: 0.1455 - val_f1: 10.3806
Epoch 49/50
87/87 - 29s - loss: 2.4035 - accuracy: 0.2550 - f1: 11.6377 - val_loss: 2.8831 - val_accuracy: 0.1636 - val_f1: 11.1135
Epoch 50/50
87/87 - 28s - loss: 2.4243 - accuracy: 0.2567 - f1: 11.2042 - val_loss: 3.1253 - val_accuracy: 0.1236 - val_f1: 10.0480
In [33]:
plot_history_scores(
    dict_history = history, 
    first_score = "accuracy", 
    second_score = "f1")

Fine tuning our homemade CNN

In [34]:
def hpt_cnn_model_builder(hp):
    model = custom_cnn_builder()

    # Tune the learning rate and beta1 for the optimizer
    # Choose an optimal value from 0.01, 0.001, or 0.0001
    hp_learning_rate = hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4])
    hp_beta1 = hp.Choice('beta_1', values=[0.9,0.95,0.99])

    model.compile(optimizer=keras.optimizers.Adam(learning_rate=hp_learning_rate,beta_1=hp_beta1),
                  loss="sparse_categorical_crossentropy",
                  metrics=['accuracy',f1])
    return model
In [35]:
tuner_cnn = kt.RandomSearch(hpt_cnn_model_builder,
    objective='val_accuracy',
    max_trials=5,
    directory='my_dir_custom_cnn',
    overwrite=True,
    project_name='custom_cnn')

stop_early = tf.keras.callbacks.EarlyStopping(monitor='val_accuracy', patience=5)

# Search best params
tuner_cnn.search(
    train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='training'),
    validation_data=train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='validation'),
    epochs=20,
    callbacks=[stop_early])
Trial 5 Complete [00h 12m 19s]
val_accuracy: 0.16545455157756805

Best val_accuracy So Far: 0.17272727191448212
Total elapsed time: 00h 53m 29s
INFO:tensorflow:Oracle triggered exit
INFO:tensorflow:Oracle triggered exit
In [36]:
# Get the optimal hyperparameters
best_hps_custom_cnn = tuner_cnn.get_best_hyperparameters(num_trials=1)[0]

print("-" * 50)
print("Custom CNN Hyperparameters optimization :")
print("-" * 50)
print(f"""
Best learning rate : {best_hps_custom_cnn.get('learning_rate')}.\n""")
print(f"""
Best beta_1 : {best_hps_custom_cnn.get('beta_1')}\n""")
--------------------------------------------------
Custom CNN Hyperparameters optimization :
--------------------------------------------------

Best learning rate : 0.001.


Best beta_1 : 0.9

In [37]:
hypermodel_custom_cnn = tuner_cnn.hypermodel.build(best_hps_custom_cnn)
history_custom_cnn = hypermodel_custom_cnn.fit(
    train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='training'), 
    epochs=EPOCHS+20,
    validation_data=train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='validation'),
    verbose=2)
Epoch 1/50
138/138 - 41s - loss: 2.9184 - accuracy: 0.1089 - f1: 15.6437 - val_loss: 3.0519 - val_accuracy: 0.0855 - val_f1: 13.7807
Epoch 2/50
138/138 - 40s - loss: 2.8523 - accuracy: 0.1357 - f1: 15.0543 - val_loss: 3.1234 - val_accuracy: 0.0855 - val_f1: 13.4704
Epoch 3/50
138/138 - 40s - loss: 2.8351 - accuracy: 0.1357 - f1: 14.8972 - val_loss: 3.0502 - val_accuracy: 0.1036 - val_f1: 12.3117
Epoch 4/50
138/138 - 41s - loss: 2.8094 - accuracy: 0.1457 - f1: 14.6115 - val_loss: 3.1274 - val_accuracy: 0.1127 - val_f1: 12.1996
Epoch 5/50
138/138 - 40s - loss: 2.7805 - accuracy: 0.1475 - f1: 14.5173 - val_loss: 2.9253 - val_accuracy: 0.1164 - val_f1: 14.9578
Epoch 6/50
138/138 - 40s - loss: 2.7623 - accuracy: 0.1530 - f1: 14.1842 - val_loss: 2.8689 - val_accuracy: 0.1182 - val_f1: 13.4488
Epoch 7/50
138/138 - 40s - loss: 2.7439 - accuracy: 0.1657 - f1: 13.8003 - val_loss: 3.2171 - val_accuracy: 0.0800 - val_f1: 10.7632
Epoch 8/50
138/138 - 41s - loss: 2.7182 - accuracy: 0.1625 - f1: 13.6464 - val_loss: 2.8940 - val_accuracy: 0.1364 - val_f1: 12.5416
Epoch 9/50
138/138 - 41s - loss: 2.7008 - accuracy: 0.1707 - f1: 13.4238 - val_loss: 2.8454 - val_accuracy: 0.1236 - val_f1: 12.6913
Epoch 10/50
138/138 - 40s - loss: 2.6840 - accuracy: 0.1702 - f1: 13.5320 - val_loss: 3.0457 - val_accuracy: 0.1200 - val_f1: 11.3072
Epoch 11/50
138/138 - 41s - loss: 2.6830 - accuracy: 0.1752 - f1: 13.2339 - val_loss: 2.7540 - val_accuracy: 0.1527 - val_f1: 13.1333
Epoch 12/50
138/138 - 41s - loss: 2.6638 - accuracy: 0.1879 - f1: 13.1131 - val_loss: 3.1885 - val_accuracy: 0.1236 - val_f1: 10.3958
Epoch 13/50
138/138 - 40s - loss: 2.6448 - accuracy: 0.1761 - f1: 13.0627 - val_loss: 2.9136 - val_accuracy: 0.1127 - val_f1: 12.0028
Epoch 14/50
138/138 - 40s - loss: 2.6379 - accuracy: 0.1902 - f1: 12.8375 - val_loss: 2.7733 - val_accuracy: 0.1327 - val_f1: 12.4096
Epoch 15/50
138/138 - 40s - loss: 2.6139 - accuracy: 0.1947 - f1: 12.6927 - val_loss: 3.1578 - val_accuracy: 0.0818 - val_f1: 10.8173
Epoch 16/50
138/138 - 40s - loss: 2.6126 - accuracy: 0.1888 - f1: 12.8389 - val_loss: 3.1419 - val_accuracy: 0.1236 - val_f1: 10.2196
Epoch 17/50
138/138 - 41s - loss: 2.5953 - accuracy: 0.1997 - f1: 12.7044 - val_loss: 3.0870 - val_accuracy: 0.1091 - val_f1: 11.3363
Epoch 18/50
138/138 - 40s - loss: 2.5700 - accuracy: 0.1911 - f1: 12.6079 - val_loss: 3.1629 - val_accuracy: 0.0927 - val_f1: 9.9708
Epoch 19/50
138/138 - 41s - loss: 2.5535 - accuracy: 0.2165 - f1: 12.5017 - val_loss: 3.0956 - val_accuracy: 0.1236 - val_f1: 10.5133
Epoch 20/50
138/138 - 40s - loss: 2.5611 - accuracy: 0.2097 - f1: 12.2634 - val_loss: 2.9716 - val_accuracy: 0.1091 - val_f1: 11.1504
Epoch 21/50
138/138 - 40s - loss: 2.5422 - accuracy: 0.2034 - f1: 12.2802 - val_loss: 3.3263 - val_accuracy: 0.1055 - val_f1: 9.8118
Epoch 22/50
138/138 - 40s - loss: 2.5319 - accuracy: 0.2143 - f1: 12.2030 - val_loss: 3.6501 - val_accuracy: 0.0982 - val_f1: 8.0871
Epoch 23/50
138/138 - 40s - loss: 2.5236 - accuracy: 0.2192 - f1: 12.1237 - val_loss: 3.0308 - val_accuracy: 0.0818 - val_f1: 12.2575
Epoch 24/50
138/138 - 40s - loss: 2.5096 - accuracy: 0.2256 - f1: 11.9818 - val_loss: 3.1815 - val_accuracy: 0.0836 - val_f1: 8.8854
Epoch 25/50
138/138 - 40s - loss: 2.4730 - accuracy: 0.2342 - f1: 11.7686 - val_loss: 2.8738 - val_accuracy: 0.1564 - val_f1: 10.9864
Epoch 26/50
138/138 - 40s - loss: 2.4714 - accuracy: 0.2274 - f1: 11.7286 - val_loss: 3.0880 - val_accuracy: 0.1218 - val_f1: 9.8891
Epoch 27/50
138/138 - 40s - loss: 2.4668 - accuracy: 0.2320 - f1: 11.7779 - val_loss: 3.1953 - val_accuracy: 0.1218 - val_f1: 8.9809
Epoch 28/50
138/138 - 40s - loss: 2.4664 - accuracy: 0.2251 - f1: 11.6850 - val_loss: 3.0974 - val_accuracy: 0.1145 - val_f1: 9.0176
Epoch 29/50
138/138 - 41s - loss: 2.4531 - accuracy: 0.2306 - f1: 11.6271 - val_loss: 2.9465 - val_accuracy: 0.0982 - val_f1: 10.0334
Epoch 30/50
138/138 - 40s - loss: 2.4313 - accuracy: 0.2483 - f1: 11.5622 - val_loss: 3.2903 - val_accuracy: 0.1236 - val_f1: 9.7572
Epoch 31/50
138/138 - 40s - loss: 2.4455 - accuracy: 0.2292 - f1: 11.5167 - val_loss: 3.4358 - val_accuracy: 0.0582 - val_f1: 6.8822
Epoch 32/50
138/138 - 40s - loss: 2.4367 - accuracy: 0.2401 - f1: 11.3645 - val_loss: 2.8721 - val_accuracy: 0.1291 - val_f1: 10.5737
Epoch 33/50
138/138 - 40s - loss: 2.4346 - accuracy: 0.2410 - f1: 11.5005 - val_loss: 2.7283 - val_accuracy: 0.1473 - val_f1: 10.6898
Epoch 34/50
138/138 - 41s - loss: 2.4114 - accuracy: 0.2356 - f1: 11.2744 - val_loss: 2.6557 - val_accuracy: 0.1400 - val_f1: 11.3199
Epoch 35/50
138/138 - 40s - loss: 2.4023 - accuracy: 0.2524 - f1: 11.2680 - val_loss: 3.5775 - val_accuracy: 0.0745 - val_f1: 6.2713
Epoch 36/50
138/138 - 40s - loss: 2.4015 - accuracy: 0.2492 - f1: 11.1696 - val_loss: 3.2939 - val_accuracy: 0.0964 - val_f1: 8.8189
Epoch 37/50
138/138 - 41s - loss: 2.3892 - accuracy: 0.2515 - f1: 11.2979 - val_loss: 3.0069 - val_accuracy: 0.1182 - val_f1: 8.6910
Epoch 38/50
138/138 - 41s - loss: 2.3607 - accuracy: 0.2615 - f1: 11.0199 - val_loss: 3.5139 - val_accuracy: 0.0836 - val_f1: 8.4659
Epoch 39/50
138/138 - 41s - loss: 2.3729 - accuracy: 0.2583 - f1: 10.9894 - val_loss: 2.9343 - val_accuracy: 0.1236 - val_f1: 9.3211
Epoch 40/50
138/138 - 40s - loss: 2.3460 - accuracy: 0.2574 - f1: 10.8772 - val_loss: 3.2550 - val_accuracy: 0.1273 - val_f1: 8.3608
Epoch 41/50
138/138 - 40s - loss: 2.3686 - accuracy: 0.2583 - f1: 10.8661 - val_loss: 3.1082 - val_accuracy: 0.1073 - val_f1: 8.4299
Epoch 42/50
138/138 - 40s - loss: 2.3652 - accuracy: 0.2651 - f1: 10.9082 - val_loss: 3.1619 - val_accuracy: 0.1400 - val_f1: 9.3610
Epoch 43/50
138/138 - 41s - loss: 2.3462 - accuracy: 0.2601 - f1: 10.8915 - val_loss: 3.3061 - val_accuracy: 0.1036 - val_f1: 6.1738
Epoch 44/50
138/138 - 41s - loss: 2.3374 - accuracy: 0.2724 - f1: 10.6982 - val_loss: 2.8561 - val_accuracy: 0.1636 - val_f1: 9.1481
Epoch 45/50
138/138 - 40s - loss: 2.3120 - accuracy: 0.2669 - f1: 10.5317 - val_loss: 3.1168 - val_accuracy: 0.1236 - val_f1: 9.8026
Epoch 46/50
138/138 - 40s - loss: 2.3327 - accuracy: 0.2864 - f1: 10.4712 - val_loss: 2.7051 - val_accuracy: 0.1836 - val_f1: 10.6376
Epoch 47/50
138/138 - 40s - loss: 2.3115 - accuracy: 0.2705 - f1: 10.7753 - val_loss: 3.3015 - val_accuracy: 0.1145 - val_f1: 8.3072
Epoch 48/50
138/138 - 41s - loss: 2.3099 - accuracy: 0.2842 - f1: 10.6564 - val_loss: 2.6356 - val_accuracy: 0.1727 - val_f1: 9.5278
Epoch 49/50
138/138 - 41s - loss: 2.3226 - accuracy: 0.2646 - f1: 10.7589 - val_loss: 2.9415 - val_accuracy: 0.1564 - val_f1: 8.2650
Epoch 50/50
138/138 - 40s - loss: 2.2923 - accuracy: 0.2810 - f1: 10.5194 - val_loss: 3.0887 - val_accuracy: 0.1655 - val_f1: 9.0531
In [38]:
plot_history_scores(
    dict_history = history_custom_cnn, 
    first_score = "accuracy", 
    second_score = "f1")
In [39]:
with plt.style.context('seaborn-whitegrid'):
    plt.figure(figsize=(13,10))
    plt.plot(history.history['val_accuracy'],
             label='CNN')
    plt.plot(history_custom_cnn.history['val_accuracy'],
             label='Custom_Hypt_CNN')
    plt.title('Accuracy of CUstom CNN vs Hypt Custom CNN',
              fontsize=18)
    plt.ylabel('Accuracy')
    plt.xlabel('epoch')
    plt.legend(loc='upper left')
    plt.show()

Using pre-trained models: VGG-16, Xception and ResNet50 with ImageNet

VGG-16

In [40]:
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
In [41]:
K.clear_session()

base_model = VGG16(weights="imagenet",
                   include_top=False,
                   input_shape=(299,299,3))

for layer in base_model.layers:
    layer.trainable = False

base_model.summary()
Model: "vgg16"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 299, 299, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 299, 299, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 299, 299, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 149, 149, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 149, 149, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 149, 149, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 74, 74, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 74, 74, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 74, 74, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 74, 74, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 37, 37, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 37, 37, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 37, 37, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 37, 37, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 18, 18, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 18, 18, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 18, 18, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 18, 18, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 9, 9, 512)         0         
=================================================================
Total params: 14,714,688
Trainable params: 0
Non-trainable params: 14,714,688
_________________________________________________________________
In [42]:
x = Flatten()(base_model.output)
x = Dropout(0.5)(x)
x = Dense(4096, activation='relu')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Dense(4096, activation='relu')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
predictions = Dense(num_breeds, activation = 'softmax')(x)

model = keras.Model(inputs=base_model.input, outputs=predictions)

model.summary()
Model: "functional_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 299, 299, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 299, 299, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 299, 299, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 149, 149, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 149, 149, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 149, 149, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 74, 74, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 74, 74, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 74, 74, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 74, 74, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 37, 37, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 37, 37, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 37, 37, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 37, 37, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 18, 18, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 18, 18, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 18, 18, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 18, 18, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 9, 9, 512)         0         
_________________________________________________________________
flatten (Flatten)            (None, 41472)             0         
_________________________________________________________________
dropout (Dropout)            (None, 41472)             0         
_________________________________________________________________
dense (Dense)                (None, 4096)              169873408 
_________________________________________________________________
batch_normalization (BatchNo (None, 4096)              16384     
_________________________________________________________________
dropout_1 (Dropout)          (None, 4096)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 4096)              16781312  
_________________________________________________________________
batch_normalization_1 (Batch (None, 4096)              16384     
_________________________________________________________________
dropout_2 (Dropout)          (None, 4096)              0         
_________________________________________________________________
dense_2 (Dense)              (None, 20)                81940     
=================================================================
Total params: 201,484,116
Trainable params: 186,753,044
Non-trainable params: 14,731,072
_________________________________________________________________
In [43]:
model.compile(loss="sparse_categorical_crossentropy", 
              optimizer="adam", 
              metrics=["accuracy",f1])
In [44]:
# Data generator on train set with Data Augmentation
# Validation set is define here
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest',
    validation_split=0.2,
    preprocessing_function=preprocess_input)

#For validation and test, just rescale
test_datagen = ImageDataGenerator(rescale=1./255)
In [45]:
history_vgg16 = model.fit(
    train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='training'),
    validation_data=train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='validation'),
    steps_per_epoch=int(np.ceil(x_train.shape[0] / (2*BATCH_SIZE))),
    epochs=EPOCHS,
    verbose=2)
Epoch 1/30
87/87 - 35s - loss: 7.0706 - accuracy: 0.1355 - f1: 2.4247 - val_loss: 22.1989 - val_accuracy: 0.0891 - val_f1: 1.2865
Epoch 2/30
87/87 - 30s - loss: 5.2675 - accuracy: 0.1753 - f1: 2.6213 - val_loss: 8.8504 - val_accuracy: 0.1509 - val_f1: 1.8163
Epoch 3/30
87/87 - 29s - loss: 4.4073 - accuracy: 0.2091 - f1: 2.7956 - val_loss: 5.1323 - val_accuracy: 0.2509 - val_f1: 2.4122
Epoch 4/30
87/87 - 30s - loss: 3.9580 - accuracy: 0.2257 - f1: 2.8712 - val_loss: 4.6864 - val_accuracy: 0.2364 - val_f1: 2.6107
Epoch 5/30
87/87 - 29s - loss: 3.8679 - accuracy: 0.2372 - f1: 2.9209 - val_loss: 4.0208 - val_accuracy: 0.2491 - val_f1: 2.7100
Epoch 6/30
87/87 - 29s - loss: 3.8435 - accuracy: 0.2422 - f1: 3.0656 - val_loss: 3.9607 - val_accuracy: 0.2509 - val_f1: 2.6505
Epoch 7/30
87/87 - 29s - loss: 3.6992 - accuracy: 0.2486 - f1: 3.0895 - val_loss: 3.9770 - val_accuracy: 0.2782 - val_f1: 2.5562
Epoch 8/30
87/87 - 29s - loss: 3.5627 - accuracy: 0.2437 - f1: 3.1308 - val_loss: 3.4982 - val_accuracy: 0.2764 - val_f1: 2.9315
Epoch 9/30
87/87 - 29s - loss: 3.5485 - accuracy: 0.2689 - f1: 2.9499 - val_loss: 3.5638 - val_accuracy: 0.2909 - val_f1: 2.8674
Epoch 10/30
87/87 - 29s - loss: 3.5665 - accuracy: 0.2812 - f1: 2.8789 - val_loss: 3.2652 - val_accuracy: 0.3036 - val_f1: 3.1729
Epoch 11/30
87/87 - 29s - loss: 3.1917 - accuracy: 0.3071 - f1: 2.9328 - val_loss: 3.2664 - val_accuracy: 0.2945 - val_f1: 3.0664
Epoch 12/30
87/87 - 29s - loss: 3.3493 - accuracy: 0.2934 - f1: 2.9743 - val_loss: 3.2332 - val_accuracy: 0.2582 - val_f1: 3.1172
Epoch 13/30
87/87 - 30s - loss: 3.3132 - accuracy: 0.2934 - f1: 2.8118 - val_loss: 3.6007 - val_accuracy: 0.2764 - val_f1: 2.8585
Epoch 14/30
87/87 - 29s - loss: 3.3506 - accuracy: 0.3050 - f1: 2.8955 - val_loss: 3.1409 - val_accuracy: 0.3073 - val_f1: 3.0443
Epoch 15/30
87/87 - 30s - loss: 3.3279 - accuracy: 0.2963 - f1: 2.9636 - val_loss: 3.1257 - val_accuracy: 0.3218 - val_f1: 3.1243
Epoch 16/30
87/87 - 30s - loss: 3.1537 - accuracy: 0.3182 - f1: 2.8970 - val_loss: 3.0412 - val_accuracy: 0.3364 - val_f1: 3.0408
Epoch 17/30
87/87 - 30s - loss: 3.2382 - accuracy: 0.3333 - f1: 2.8632 - val_loss: 2.9293 - val_accuracy: 0.3218 - val_f1: 3.0504
Epoch 18/30
87/87 - 29s - loss: 3.1442 - accuracy: 0.3247 - f1: 2.7818 - val_loss: 3.4495 - val_accuracy: 0.3255 - val_f1: 2.7486
Epoch 19/30
87/87 - 30s - loss: 3.0137 - accuracy: 0.3288 - f1: 2.8966 - val_loss: 3.1816 - val_accuracy: 0.3000 - val_f1: 2.8953
Epoch 20/30
87/87 - 29s - loss: 3.1842 - accuracy: 0.3302 - f1: 2.8529 - val_loss: 2.9919 - val_accuracy: 0.3218 - val_f1: 2.9402
Epoch 21/30
87/87 - 29s - loss: 3.0656 - accuracy: 0.3302 - f1: 2.8694 - val_loss: 2.7707 - val_accuracy: 0.3636 - val_f1: 2.8306
Epoch 22/30
87/87 - 30s - loss: 2.8418 - accuracy: 0.3576 - f1: 2.9583 - val_loss: 3.0275 - val_accuracy: 0.3255 - val_f1: 3.0509
Epoch 23/30
87/87 - 30s - loss: 2.8766 - accuracy: 0.3491 - f1: 2.9301 - val_loss: 3.3398 - val_accuracy: 0.3091 - val_f1: 3.0209
Epoch 24/30
87/87 - 30s - loss: 2.9072 - accuracy: 0.3549 - f1: 2.8626 - val_loss: 2.8609 - val_accuracy: 0.3455 - val_f1: 3.0026
Epoch 25/30
87/87 - 30s - loss: 2.7959 - accuracy: 0.3598 - f1: 2.9092 - val_loss: 3.0082 - val_accuracy: 0.3364 - val_f1: 3.0628
Epoch 26/30
87/87 - 29s - loss: 2.9428 - accuracy: 0.3592 - f1: 2.7857 - val_loss: 2.8505 - val_accuracy: 0.3473 - val_f1: 2.9738
Epoch 27/30
87/87 - 29s - loss: 2.8473 - accuracy: 0.3526 - f1: 2.8507 - val_loss: 2.8911 - val_accuracy: 0.3564 - val_f1: 3.0385
Epoch 28/30
87/87 - 29s - loss: 2.7084 - accuracy: 0.3764 - f1: 2.7532 - val_loss: 2.6779 - val_accuracy: 0.3691 - val_f1: 3.1643
Epoch 29/30
87/87 - 29s - loss: 2.7212 - accuracy: 0.3497 - f1: 2.9646 - val_loss: 3.0270 - val_accuracy: 0.3527 - val_f1: 3.2023
Epoch 30/30
87/87 - 30s - loss: 2.8239 - accuracy: 0.3427 - f1: 2.8628 - val_loss: 2.7910 - val_accuracy: 0.3327 - val_f1: 3.3722
In [46]:
plot_history_scores(
    dict_history = history_vgg16, 
    first_score = "accuracy", 
    second_score = "f1")

Xception

In [47]:
from tensorflow.keras.applications.xception import Xception
In [48]:
K.clear_session()

xception_model = Xception(weights="imagenet",
                   include_top=False,
                   pooling='avg',
                   input_shape=(299,299,3))

for layer in xception_model.layers:
    layer.trainable = False
In [49]:
# Add new fully-connected layers
base_xception = xception_model.output
base_xception = Dense(128, activation='relu')(base_xception)
base_xception = Dropout(0.2)(base_xception)
# Output : new classifier
predictions = Dense(num_breeds, activation='softmax')(base_xception)

# Define new model
my_xcept_model = Model(inputs=xception_model.input,
                       outputs=predictions)
In [50]:
my_xcept_model.compile(optimizer="adam",
                       loss="sparse_categorical_crossentropy",
                       metrics=["accuracy", f1])
In [51]:
xception_model.summary()
Model: "xception"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, 299, 299, 3) 0                                            
__________________________________________________________________________________________________
block1_conv1 (Conv2D)           (None, 149, 149, 32) 864         input_1[0][0]                    
__________________________________________________________________________________________________
block1_conv1_bn (BatchNormaliza (None, 149, 149, 32) 128         block1_conv1[0][0]               
__________________________________________________________________________________________________
block1_conv1_act (Activation)   (None, 149, 149, 32) 0           block1_conv1_bn[0][0]            
__________________________________________________________________________________________________
block1_conv2 (Conv2D)           (None, 147, 147, 64) 18432       block1_conv1_act[0][0]           
__________________________________________________________________________________________________
block1_conv2_bn (BatchNormaliza (None, 147, 147, 64) 256         block1_conv2[0][0]               
__________________________________________________________________________________________________
block1_conv2_act (Activation)   (None, 147, 147, 64) 0           block1_conv2_bn[0][0]            
__________________________________________________________________________________________________
block2_sepconv1 (SeparableConv2 (None, 147, 147, 128 8768        block1_conv2_act[0][0]           
__________________________________________________________________________________________________
block2_sepconv1_bn (BatchNormal (None, 147, 147, 128 512         block2_sepconv1[0][0]            
__________________________________________________________________________________________________
block2_sepconv2_act (Activation (None, 147, 147, 128 0           block2_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block2_sepconv2 (SeparableConv2 (None, 147, 147, 128 17536       block2_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block2_sepconv2_bn (BatchNormal (None, 147, 147, 128 512         block2_sepconv2[0][0]            
__________________________________________________________________________________________________
conv2d (Conv2D)                 (None, 74, 74, 128)  8192        block1_conv2_act[0][0]           
__________________________________________________________________________________________________
block2_pool (MaxPooling2D)      (None, 74, 74, 128)  0           block2_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
batch_normalization (BatchNorma (None, 74, 74, 128)  512         conv2d[0][0]                     
__________________________________________________________________________________________________
add (Add)                       (None, 74, 74, 128)  0           block2_pool[0][0]                
                                                                 batch_normalization[0][0]        
__________________________________________________________________________________________________
block3_sepconv1_act (Activation (None, 74, 74, 128)  0           add[0][0]                        
__________________________________________________________________________________________________
block3_sepconv1 (SeparableConv2 (None, 74, 74, 256)  33920       block3_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block3_sepconv1_bn (BatchNormal (None, 74, 74, 256)  1024        block3_sepconv1[0][0]            
__________________________________________________________________________________________________
block3_sepconv2_act (Activation (None, 74, 74, 256)  0           block3_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block3_sepconv2 (SeparableConv2 (None, 74, 74, 256)  67840       block3_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block3_sepconv2_bn (BatchNormal (None, 74, 74, 256)  1024        block3_sepconv2[0][0]            
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 37, 37, 256)  32768       add[0][0]                        
__________________________________________________________________________________________________
block3_pool (MaxPooling2D)      (None, 37, 37, 256)  0           block3_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 37, 37, 256)  1024        conv2d_1[0][0]                   
__________________________________________________________________________________________________
add_1 (Add)                     (None, 37, 37, 256)  0           block3_pool[0][0]                
                                                                 batch_normalization_1[0][0]      
__________________________________________________________________________________________________
block4_sepconv1_act (Activation (None, 37, 37, 256)  0           add_1[0][0]                      
__________________________________________________________________________________________________
block4_sepconv1 (SeparableConv2 (None, 37, 37, 728)  188672      block4_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block4_sepconv1_bn (BatchNormal (None, 37, 37, 728)  2912        block4_sepconv1[0][0]            
__________________________________________________________________________________________________
block4_sepconv2_act (Activation (None, 37, 37, 728)  0           block4_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block4_sepconv2 (SeparableConv2 (None, 37, 37, 728)  536536      block4_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block4_sepconv2_bn (BatchNormal (None, 37, 37, 728)  2912        block4_sepconv2[0][0]            
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 19, 19, 728)  186368      add_1[0][0]                      
__________________________________________________________________________________________________
block4_pool (MaxPooling2D)      (None, 19, 19, 728)  0           block4_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
batch_normalization_2 (BatchNor (None, 19, 19, 728)  2912        conv2d_2[0][0]                   
__________________________________________________________________________________________________
add_2 (Add)                     (None, 19, 19, 728)  0           block4_pool[0][0]                
                                                                 batch_normalization_2[0][0]      
__________________________________________________________________________________________________
block5_sepconv1_act (Activation (None, 19, 19, 728)  0           add_2[0][0]                      
__________________________________________________________________________________________________
block5_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block5_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block5_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block5_sepconv1[0][0]            
__________________________________________________________________________________________________
block5_sepconv2_act (Activation (None, 19, 19, 728)  0           block5_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block5_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block5_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block5_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block5_sepconv2[0][0]            
__________________________________________________________________________________________________
block5_sepconv3_act (Activation (None, 19, 19, 728)  0           block5_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block5_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block5_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block5_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block5_sepconv3[0][0]            
__________________________________________________________________________________________________
add_3 (Add)                     (None, 19, 19, 728)  0           block5_sepconv3_bn[0][0]         
                                                                 add_2[0][0]                      
__________________________________________________________________________________________________
block6_sepconv1_act (Activation (None, 19, 19, 728)  0           add_3[0][0]                      
__________________________________________________________________________________________________
block6_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block6_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block6_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block6_sepconv1[0][0]            
__________________________________________________________________________________________________
block6_sepconv2_act (Activation (None, 19, 19, 728)  0           block6_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block6_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block6_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block6_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block6_sepconv2[0][0]            
__________________________________________________________________________________________________
block6_sepconv3_act (Activation (None, 19, 19, 728)  0           block6_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block6_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block6_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block6_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block6_sepconv3[0][0]            
__________________________________________________________________________________________________
add_4 (Add)                     (None, 19, 19, 728)  0           block6_sepconv3_bn[0][0]         
                                                                 add_3[0][0]                      
__________________________________________________________________________________________________
block7_sepconv1_act (Activation (None, 19, 19, 728)  0           add_4[0][0]                      
__________________________________________________________________________________________________
block7_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block7_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block7_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block7_sepconv1[0][0]            
__________________________________________________________________________________________________
block7_sepconv2_act (Activation (None, 19, 19, 728)  0           block7_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block7_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block7_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block7_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block7_sepconv2[0][0]            
__________________________________________________________________________________________________
block7_sepconv3_act (Activation (None, 19, 19, 728)  0           block7_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block7_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block7_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block7_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block7_sepconv3[0][0]            
__________________________________________________________________________________________________
add_5 (Add)                     (None, 19, 19, 728)  0           block7_sepconv3_bn[0][0]         
                                                                 add_4[0][0]                      
__________________________________________________________________________________________________
block8_sepconv1_act (Activation (None, 19, 19, 728)  0           add_5[0][0]                      
__________________________________________________________________________________________________
block8_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block8_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block8_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block8_sepconv1[0][0]            
__________________________________________________________________________________________________
block8_sepconv2_act (Activation (None, 19, 19, 728)  0           block8_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block8_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block8_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block8_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block8_sepconv2[0][0]            
__________________________________________________________________________________________________
block8_sepconv3_act (Activation (None, 19, 19, 728)  0           block8_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block8_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block8_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block8_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block8_sepconv3[0][0]            
__________________________________________________________________________________________________
add_6 (Add)                     (None, 19, 19, 728)  0           block8_sepconv3_bn[0][0]         
                                                                 add_5[0][0]                      
__________________________________________________________________________________________________
block9_sepconv1_act (Activation (None, 19, 19, 728)  0           add_6[0][0]                      
__________________________________________________________________________________________________
block9_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block9_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block9_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block9_sepconv1[0][0]            
__________________________________________________________________________________________________
block9_sepconv2_act (Activation (None, 19, 19, 728)  0           block9_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block9_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block9_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block9_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block9_sepconv2[0][0]            
__________________________________________________________________________________________________
block9_sepconv3_act (Activation (None, 19, 19, 728)  0           block9_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block9_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block9_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block9_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block9_sepconv3[0][0]            
__________________________________________________________________________________________________
add_7 (Add)                     (None, 19, 19, 728)  0           block9_sepconv3_bn[0][0]         
                                                                 add_6[0][0]                      
__________________________________________________________________________________________________
block10_sepconv1_act (Activatio (None, 19, 19, 728)  0           add_7[0][0]                      
__________________________________________________________________________________________________
block10_sepconv1 (SeparableConv (None, 19, 19, 728)  536536      block10_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block10_sepconv1_bn (BatchNorma (None, 19, 19, 728)  2912        block10_sepconv1[0][0]           
__________________________________________________________________________________________________
block10_sepconv2_act (Activatio (None, 19, 19, 728)  0           block10_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block10_sepconv2 (SeparableConv (None, 19, 19, 728)  536536      block10_sepconv2_act[0][0]       
__________________________________________________________________________________________________
block10_sepconv2_bn (BatchNorma (None, 19, 19, 728)  2912        block10_sepconv2[0][0]           
__________________________________________________________________________________________________
block10_sepconv3_act (Activatio (None, 19, 19, 728)  0           block10_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
block10_sepconv3 (SeparableConv (None, 19, 19, 728)  536536      block10_sepconv3_act[0][0]       
__________________________________________________________________________________________________
block10_sepconv3_bn (BatchNorma (None, 19, 19, 728)  2912        block10_sepconv3[0][0]           
__________________________________________________________________________________________________
add_8 (Add)                     (None, 19, 19, 728)  0           block10_sepconv3_bn[0][0]        
                                                                 add_7[0][0]                      
__________________________________________________________________________________________________
block11_sepconv1_act (Activatio (None, 19, 19, 728)  0           add_8[0][0]                      
__________________________________________________________________________________________________
block11_sepconv1 (SeparableConv (None, 19, 19, 728)  536536      block11_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block11_sepconv1_bn (BatchNorma (None, 19, 19, 728)  2912        block11_sepconv1[0][0]           
__________________________________________________________________________________________________
block11_sepconv2_act (Activatio (None, 19, 19, 728)  0           block11_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block11_sepconv2 (SeparableConv (None, 19, 19, 728)  536536      block11_sepconv2_act[0][0]       
__________________________________________________________________________________________________
block11_sepconv2_bn (BatchNorma (None, 19, 19, 728)  2912        block11_sepconv2[0][0]           
__________________________________________________________________________________________________
block11_sepconv3_act (Activatio (None, 19, 19, 728)  0           block11_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
block11_sepconv3 (SeparableConv (None, 19, 19, 728)  536536      block11_sepconv3_act[0][0]       
__________________________________________________________________________________________________
block11_sepconv3_bn (BatchNorma (None, 19, 19, 728)  2912        block11_sepconv3[0][0]           
__________________________________________________________________________________________________
add_9 (Add)                     (None, 19, 19, 728)  0           block11_sepconv3_bn[0][0]        
                                                                 add_8[0][0]                      
__________________________________________________________________________________________________
block12_sepconv1_act (Activatio (None, 19, 19, 728)  0           add_9[0][0]                      
__________________________________________________________________________________________________
block12_sepconv1 (SeparableConv (None, 19, 19, 728)  536536      block12_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block12_sepconv1_bn (BatchNorma (None, 19, 19, 728)  2912        block12_sepconv1[0][0]           
__________________________________________________________________________________________________
block12_sepconv2_act (Activatio (None, 19, 19, 728)  0           block12_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block12_sepconv2 (SeparableConv (None, 19, 19, 728)  536536      block12_sepconv2_act[0][0]       
__________________________________________________________________________________________________
block12_sepconv2_bn (BatchNorma (None, 19, 19, 728)  2912        block12_sepconv2[0][0]           
__________________________________________________________________________________________________
block12_sepconv3_act (Activatio (None, 19, 19, 728)  0           block12_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
block12_sepconv3 (SeparableConv (None, 19, 19, 728)  536536      block12_sepconv3_act[0][0]       
__________________________________________________________________________________________________
block12_sepconv3_bn (BatchNorma (None, 19, 19, 728)  2912        block12_sepconv3[0][0]           
__________________________________________________________________________________________________
add_10 (Add)                    (None, 19, 19, 728)  0           block12_sepconv3_bn[0][0]        
                                                                 add_9[0][0]                      
__________________________________________________________________________________________________
block13_sepconv1_act (Activatio (None, 19, 19, 728)  0           add_10[0][0]                     
__________________________________________________________________________________________________
block13_sepconv1 (SeparableConv (None, 19, 19, 728)  536536      block13_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block13_sepconv1_bn (BatchNorma (None, 19, 19, 728)  2912        block13_sepconv1[0][0]           
__________________________________________________________________________________________________
block13_sepconv2_act (Activatio (None, 19, 19, 728)  0           block13_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block13_sepconv2 (SeparableConv (None, 19, 19, 1024) 752024      block13_sepconv2_act[0][0]       
__________________________________________________________________________________________________
block13_sepconv2_bn (BatchNorma (None, 19, 19, 1024) 4096        block13_sepconv2[0][0]           
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, 10, 10, 1024) 745472      add_10[0][0]                     
__________________________________________________________________________________________________
block13_pool (MaxPooling2D)     (None, 10, 10, 1024) 0           block13_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
batch_normalization_3 (BatchNor (None, 10, 10, 1024) 4096        conv2d_3[0][0]                   
__________________________________________________________________________________________________
add_11 (Add)                    (None, 10, 10, 1024) 0           block13_pool[0][0]               
                                                                 batch_normalization_3[0][0]      
__________________________________________________________________________________________________
block14_sepconv1 (SeparableConv (None, 10, 10, 1536) 1582080     add_11[0][0]                     
__________________________________________________________________________________________________
block14_sepconv1_bn (BatchNorma (None, 10, 10, 1536) 6144        block14_sepconv1[0][0]           
__________________________________________________________________________________________________
block14_sepconv1_act (Activatio (None, 10, 10, 1536) 0           block14_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block14_sepconv2 (SeparableConv (None, 10, 10, 2048) 3159552     block14_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block14_sepconv2_bn (BatchNorma (None, 10, 10, 2048) 8192        block14_sepconv2[0][0]           
__________________________________________________________________________________________________
block14_sepconv2_act (Activatio (None, 10, 10, 2048) 0           block14_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
global_average_pooling2d (Globa (None, 2048)         0           block14_sepconv2_act[0][0]       
==================================================================================================
Total params: 20,861,480
Trainable params: 0
Non-trainable params: 20,861,480
__________________________________________________________________________________________________
In [52]:
len(xception_model.layers)
Out[52]:
133
In [53]:
my_xcept_model.summary()
Model: "functional_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, 299, 299, 3) 0                                            
__________________________________________________________________________________________________
block1_conv1 (Conv2D)           (None, 149, 149, 32) 864         input_1[0][0]                    
__________________________________________________________________________________________________
block1_conv1_bn (BatchNormaliza (None, 149, 149, 32) 128         block1_conv1[0][0]               
__________________________________________________________________________________________________
block1_conv1_act (Activation)   (None, 149, 149, 32) 0           block1_conv1_bn[0][0]            
__________________________________________________________________________________________________
block1_conv2 (Conv2D)           (None, 147, 147, 64) 18432       block1_conv1_act[0][0]           
__________________________________________________________________________________________________
block1_conv2_bn (BatchNormaliza (None, 147, 147, 64) 256         block1_conv2[0][0]               
__________________________________________________________________________________________________
block1_conv2_act (Activation)   (None, 147, 147, 64) 0           block1_conv2_bn[0][0]            
__________________________________________________________________________________________________
block2_sepconv1 (SeparableConv2 (None, 147, 147, 128 8768        block1_conv2_act[0][0]           
__________________________________________________________________________________________________
block2_sepconv1_bn (BatchNormal (None, 147, 147, 128 512         block2_sepconv1[0][0]            
__________________________________________________________________________________________________
block2_sepconv2_act (Activation (None, 147, 147, 128 0           block2_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block2_sepconv2 (SeparableConv2 (None, 147, 147, 128 17536       block2_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block2_sepconv2_bn (BatchNormal (None, 147, 147, 128 512         block2_sepconv2[0][0]            
__________________________________________________________________________________________________
conv2d (Conv2D)                 (None, 74, 74, 128)  8192        block1_conv2_act[0][0]           
__________________________________________________________________________________________________
block2_pool (MaxPooling2D)      (None, 74, 74, 128)  0           block2_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
batch_normalization (BatchNorma (None, 74, 74, 128)  512         conv2d[0][0]                     
__________________________________________________________________________________________________
add (Add)                       (None, 74, 74, 128)  0           block2_pool[0][0]                
                                                                 batch_normalization[0][0]        
__________________________________________________________________________________________________
block3_sepconv1_act (Activation (None, 74, 74, 128)  0           add[0][0]                        
__________________________________________________________________________________________________
block3_sepconv1 (SeparableConv2 (None, 74, 74, 256)  33920       block3_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block3_sepconv1_bn (BatchNormal (None, 74, 74, 256)  1024        block3_sepconv1[0][0]            
__________________________________________________________________________________________________
block3_sepconv2_act (Activation (None, 74, 74, 256)  0           block3_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block3_sepconv2 (SeparableConv2 (None, 74, 74, 256)  67840       block3_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block3_sepconv2_bn (BatchNormal (None, 74, 74, 256)  1024        block3_sepconv2[0][0]            
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 37, 37, 256)  32768       add[0][0]                        
__________________________________________________________________________________________________
block3_pool (MaxPooling2D)      (None, 37, 37, 256)  0           block3_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 37, 37, 256)  1024        conv2d_1[0][0]                   
__________________________________________________________________________________________________
add_1 (Add)                     (None, 37, 37, 256)  0           block3_pool[0][0]                
                                                                 batch_normalization_1[0][0]      
__________________________________________________________________________________________________
block4_sepconv1_act (Activation (None, 37, 37, 256)  0           add_1[0][0]                      
__________________________________________________________________________________________________
block4_sepconv1 (SeparableConv2 (None, 37, 37, 728)  188672      block4_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block4_sepconv1_bn (BatchNormal (None, 37, 37, 728)  2912        block4_sepconv1[0][0]            
__________________________________________________________________________________________________
block4_sepconv2_act (Activation (None, 37, 37, 728)  0           block4_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block4_sepconv2 (SeparableConv2 (None, 37, 37, 728)  536536      block4_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block4_sepconv2_bn (BatchNormal (None, 37, 37, 728)  2912        block4_sepconv2[0][0]            
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 19, 19, 728)  186368      add_1[0][0]                      
__________________________________________________________________________________________________
block4_pool (MaxPooling2D)      (None, 19, 19, 728)  0           block4_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
batch_normalization_2 (BatchNor (None, 19, 19, 728)  2912        conv2d_2[0][0]                   
__________________________________________________________________________________________________
add_2 (Add)                     (None, 19, 19, 728)  0           block4_pool[0][0]                
                                                                 batch_normalization_2[0][0]      
__________________________________________________________________________________________________
block5_sepconv1_act (Activation (None, 19, 19, 728)  0           add_2[0][0]                      
__________________________________________________________________________________________________
block5_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block5_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block5_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block5_sepconv1[0][0]            
__________________________________________________________________________________________________
block5_sepconv2_act (Activation (None, 19, 19, 728)  0           block5_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block5_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block5_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block5_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block5_sepconv2[0][0]            
__________________________________________________________________________________________________
block5_sepconv3_act (Activation (None, 19, 19, 728)  0           block5_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block5_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block5_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block5_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block5_sepconv3[0][0]            
__________________________________________________________________________________________________
add_3 (Add)                     (None, 19, 19, 728)  0           block5_sepconv3_bn[0][0]         
                                                                 add_2[0][0]                      
__________________________________________________________________________________________________
block6_sepconv1_act (Activation (None, 19, 19, 728)  0           add_3[0][0]                      
__________________________________________________________________________________________________
block6_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block6_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block6_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block6_sepconv1[0][0]            
__________________________________________________________________________________________________
block6_sepconv2_act (Activation (None, 19, 19, 728)  0           block6_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block6_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block6_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block6_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block6_sepconv2[0][0]            
__________________________________________________________________________________________________
block6_sepconv3_act (Activation (None, 19, 19, 728)  0           block6_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block6_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block6_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block6_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block6_sepconv3[0][0]            
__________________________________________________________________________________________________
add_4 (Add)                     (None, 19, 19, 728)  0           block6_sepconv3_bn[0][0]         
                                                                 add_3[0][0]                      
__________________________________________________________________________________________________
block7_sepconv1_act (Activation (None, 19, 19, 728)  0           add_4[0][0]                      
__________________________________________________________________________________________________
block7_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block7_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block7_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block7_sepconv1[0][0]            
__________________________________________________________________________________________________
block7_sepconv2_act (Activation (None, 19, 19, 728)  0           block7_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block7_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block7_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block7_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block7_sepconv2[0][0]            
__________________________________________________________________________________________________
block7_sepconv3_act (Activation (None, 19, 19, 728)  0           block7_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block7_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block7_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block7_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block7_sepconv3[0][0]            
__________________________________________________________________________________________________
add_5 (Add)                     (None, 19, 19, 728)  0           block7_sepconv3_bn[0][0]         
                                                                 add_4[0][0]                      
__________________________________________________________________________________________________
block8_sepconv1_act (Activation (None, 19, 19, 728)  0           add_5[0][0]                      
__________________________________________________________________________________________________
block8_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block8_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block8_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block8_sepconv1[0][0]            
__________________________________________________________________________________________________
block8_sepconv2_act (Activation (None, 19, 19, 728)  0           block8_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block8_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block8_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block8_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block8_sepconv2[0][0]            
__________________________________________________________________________________________________
block8_sepconv3_act (Activation (None, 19, 19, 728)  0           block8_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block8_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block8_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block8_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block8_sepconv3[0][0]            
__________________________________________________________________________________________________
add_6 (Add)                     (None, 19, 19, 728)  0           block8_sepconv3_bn[0][0]         
                                                                 add_5[0][0]                      
__________________________________________________________________________________________________
block9_sepconv1_act (Activation (None, 19, 19, 728)  0           add_6[0][0]                      
__________________________________________________________________________________________________
block9_sepconv1 (SeparableConv2 (None, 19, 19, 728)  536536      block9_sepconv1_act[0][0]        
__________________________________________________________________________________________________
block9_sepconv1_bn (BatchNormal (None, 19, 19, 728)  2912        block9_sepconv1[0][0]            
__________________________________________________________________________________________________
block9_sepconv2_act (Activation (None, 19, 19, 728)  0           block9_sepconv1_bn[0][0]         
__________________________________________________________________________________________________
block9_sepconv2 (SeparableConv2 (None, 19, 19, 728)  536536      block9_sepconv2_act[0][0]        
__________________________________________________________________________________________________
block9_sepconv2_bn (BatchNormal (None, 19, 19, 728)  2912        block9_sepconv2[0][0]            
__________________________________________________________________________________________________
block9_sepconv3_act (Activation (None, 19, 19, 728)  0           block9_sepconv2_bn[0][0]         
__________________________________________________________________________________________________
block9_sepconv3 (SeparableConv2 (None, 19, 19, 728)  536536      block9_sepconv3_act[0][0]        
__________________________________________________________________________________________________
block9_sepconv3_bn (BatchNormal (None, 19, 19, 728)  2912        block9_sepconv3[0][0]            
__________________________________________________________________________________________________
add_7 (Add)                     (None, 19, 19, 728)  0           block9_sepconv3_bn[0][0]         
                                                                 add_6[0][0]                      
__________________________________________________________________________________________________
block10_sepconv1_act (Activatio (None, 19, 19, 728)  0           add_7[0][0]                      
__________________________________________________________________________________________________
block10_sepconv1 (SeparableConv (None, 19, 19, 728)  536536      block10_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block10_sepconv1_bn (BatchNorma (None, 19, 19, 728)  2912        block10_sepconv1[0][0]           
__________________________________________________________________________________________________
block10_sepconv2_act (Activatio (None, 19, 19, 728)  0           block10_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block10_sepconv2 (SeparableConv (None, 19, 19, 728)  536536      block10_sepconv2_act[0][0]       
__________________________________________________________________________________________________
block10_sepconv2_bn (BatchNorma (None, 19, 19, 728)  2912        block10_sepconv2[0][0]           
__________________________________________________________________________________________________
block10_sepconv3_act (Activatio (None, 19, 19, 728)  0           block10_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
block10_sepconv3 (SeparableConv (None, 19, 19, 728)  536536      block10_sepconv3_act[0][0]       
__________________________________________________________________________________________________
block10_sepconv3_bn (BatchNorma (None, 19, 19, 728)  2912        block10_sepconv3[0][0]           
__________________________________________________________________________________________________
add_8 (Add)                     (None, 19, 19, 728)  0           block10_sepconv3_bn[0][0]        
                                                                 add_7[0][0]                      
__________________________________________________________________________________________________
block11_sepconv1_act (Activatio (None, 19, 19, 728)  0           add_8[0][0]                      
__________________________________________________________________________________________________
block11_sepconv1 (SeparableConv (None, 19, 19, 728)  536536      block11_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block11_sepconv1_bn (BatchNorma (None, 19, 19, 728)  2912        block11_sepconv1[0][0]           
__________________________________________________________________________________________________
block11_sepconv2_act (Activatio (None, 19, 19, 728)  0           block11_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block11_sepconv2 (SeparableConv (None, 19, 19, 728)  536536      block11_sepconv2_act[0][0]       
__________________________________________________________________________________________________
block11_sepconv2_bn (BatchNorma (None, 19, 19, 728)  2912        block11_sepconv2[0][0]           
__________________________________________________________________________________________________
block11_sepconv3_act (Activatio (None, 19, 19, 728)  0           block11_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
block11_sepconv3 (SeparableConv (None, 19, 19, 728)  536536      block11_sepconv3_act[0][0]       
__________________________________________________________________________________________________
block11_sepconv3_bn (BatchNorma (None, 19, 19, 728)  2912        block11_sepconv3[0][0]           
__________________________________________________________________________________________________
add_9 (Add)                     (None, 19, 19, 728)  0           block11_sepconv3_bn[0][0]        
                                                                 add_8[0][0]                      
__________________________________________________________________________________________________
block12_sepconv1_act (Activatio (None, 19, 19, 728)  0           add_9[0][0]                      
__________________________________________________________________________________________________
block12_sepconv1 (SeparableConv (None, 19, 19, 728)  536536      block12_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block12_sepconv1_bn (BatchNorma (None, 19, 19, 728)  2912        block12_sepconv1[0][0]           
__________________________________________________________________________________________________
block12_sepconv2_act (Activatio (None, 19, 19, 728)  0           block12_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block12_sepconv2 (SeparableConv (None, 19, 19, 728)  536536      block12_sepconv2_act[0][0]       
__________________________________________________________________________________________________
block12_sepconv2_bn (BatchNorma (None, 19, 19, 728)  2912        block12_sepconv2[0][0]           
__________________________________________________________________________________________________
block12_sepconv3_act (Activatio (None, 19, 19, 728)  0           block12_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
block12_sepconv3 (SeparableConv (None, 19, 19, 728)  536536      block12_sepconv3_act[0][0]       
__________________________________________________________________________________________________
block12_sepconv3_bn (BatchNorma (None, 19, 19, 728)  2912        block12_sepconv3[0][0]           
__________________________________________________________________________________________________
add_10 (Add)                    (None, 19, 19, 728)  0           block12_sepconv3_bn[0][0]        
                                                                 add_9[0][0]                      
__________________________________________________________________________________________________
block13_sepconv1_act (Activatio (None, 19, 19, 728)  0           add_10[0][0]                     
__________________________________________________________________________________________________
block13_sepconv1 (SeparableConv (None, 19, 19, 728)  536536      block13_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block13_sepconv1_bn (BatchNorma (None, 19, 19, 728)  2912        block13_sepconv1[0][0]           
__________________________________________________________________________________________________
block13_sepconv2_act (Activatio (None, 19, 19, 728)  0           block13_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block13_sepconv2 (SeparableConv (None, 19, 19, 1024) 752024      block13_sepconv2_act[0][0]       
__________________________________________________________________________________________________
block13_sepconv2_bn (BatchNorma (None, 19, 19, 1024) 4096        block13_sepconv2[0][0]           
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, 10, 10, 1024) 745472      add_10[0][0]                     
__________________________________________________________________________________________________
block13_pool (MaxPooling2D)     (None, 10, 10, 1024) 0           block13_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
batch_normalization_3 (BatchNor (None, 10, 10, 1024) 4096        conv2d_3[0][0]                   
__________________________________________________________________________________________________
add_11 (Add)                    (None, 10, 10, 1024) 0           block13_pool[0][0]               
                                                                 batch_normalization_3[0][0]      
__________________________________________________________________________________________________
block14_sepconv1 (SeparableConv (None, 10, 10, 1536) 1582080     add_11[0][0]                     
__________________________________________________________________________________________________
block14_sepconv1_bn (BatchNorma (None, 10, 10, 1536) 6144        block14_sepconv1[0][0]           
__________________________________________________________________________________________________
block14_sepconv1_act (Activatio (None, 10, 10, 1536) 0           block14_sepconv1_bn[0][0]        
__________________________________________________________________________________________________
block14_sepconv2 (SeparableConv (None, 10, 10, 2048) 3159552     block14_sepconv1_act[0][0]       
__________________________________________________________________________________________________
block14_sepconv2_bn (BatchNorma (None, 10, 10, 2048) 8192        block14_sepconv2[0][0]           
__________________________________________________________________________________________________
block14_sepconv2_act (Activatio (None, 10, 10, 2048) 0           block14_sepconv2_bn[0][0]        
__________________________________________________________________________________________________
global_average_pooling2d (Globa (None, 2048)         0           block14_sepconv2_act[0][0]       
__________________________________________________________________________________________________
dense (Dense)                   (None, 128)          262272      global_average_pooling2d[0][0]   
__________________________________________________________________________________________________
dropout (Dropout)               (None, 128)          0           dense[0][0]                      
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 20)           2580        dropout[0][0]                    
==================================================================================================
Total params: 21,126,332
Trainable params: 264,852
Non-trainable params: 20,861,480
__________________________________________________________________________________________________
In [54]:
## Data generator on train set with Data Augmentation
# and preprocess_input Xception
# Validation set is define here
train_datagen = ImageDataGenerator(
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest',
    validation_split=0.2,
    preprocessing_function=tf.keras.applications.xception.preprocess_input)

#For validation and test, just rescale
test_datagen = ImageDataGenerator(
    preprocessing_function=tf.keras.applications.xception.preprocess_input)
In [55]:
history_xcept = my_xcept_model.fit(
    train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='training'),
    validation_data=train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='validation'),
    steps_per_epoch=int(np.ceil(x_train.shape[0] / (2*BATCH_SIZE))),
    epochs=EPOCHS,
    verbose=2)
Epoch 1/30
87/87 - 30s - loss: 1.6749 - accuracy: 0.5223 - f1: 7.6336 - val_loss: 0.9941 - val_accuracy: 0.6855 - val_f1: 3.7388
Epoch 2/30
87/87 - 29s - loss: 0.9110 - accuracy: 0.7066 - f1: 3.0481 - val_loss: 0.8654 - val_accuracy: 0.7345 - val_f1: 3.0371
Epoch 3/30
87/87 - 29s - loss: 0.7671 - accuracy: 0.7664 - f1: 2.6818 - val_loss: 0.7354 - val_accuracy: 0.7509 - val_f1: 2.5929
Epoch 4/30
87/87 - 29s - loss: 0.7457 - accuracy: 0.7513 - f1: 2.5212 - val_loss: 0.7188 - val_accuracy: 0.7327 - val_f1: 2.5175
Epoch 5/30
87/87 - 29s - loss: 0.7035 - accuracy: 0.7622 - f1: 2.3432 - val_loss: 0.6631 - val_accuracy: 0.7727 - val_f1: 2.2049
Epoch 6/30
87/87 - 29s - loss: 0.6323 - accuracy: 0.7895 - f1: 2.3040 - val_loss: 0.7210 - val_accuracy: 0.7655 - val_f1: 2.2191
Epoch 7/30
87/87 - 29s - loss: 0.6144 - accuracy: 0.7938 - f1: 2.1768 - val_loss: 0.6786 - val_accuracy: 0.7673 - val_f1: 2.0534
Epoch 8/30
87/87 - 29s - loss: 0.6113 - accuracy: 0.7902 - f1: 2.1281 - val_loss: 0.6413 - val_accuracy: 0.7891 - val_f1: 2.0602
Epoch 9/30
87/87 - 29s - loss: 0.5567 - accuracy: 0.8183 - f1: 2.0570 - val_loss: 0.7026 - val_accuracy: 0.7673 - val_f1: 2.0375
Epoch 10/30
87/87 - 29s - loss: 0.5583 - accuracy: 0.8097 - f1: 1.9332 - val_loss: 0.6842 - val_accuracy: 0.7618 - val_f1: 2.0973
Epoch 11/30
87/87 - 29s - loss: 0.5009 - accuracy: 0.8305 - f1: 1.9346 - val_loss: 0.6325 - val_accuracy: 0.7727 - val_f1: 1.9765
Epoch 12/30
87/87 - 29s - loss: 0.4910 - accuracy: 0.8356 - f1: 1.8628 - val_loss: 0.7186 - val_accuracy: 0.7709 - val_f1: 2.0239
Epoch 13/30
87/87 - 29s - loss: 0.5275 - accuracy: 0.8190 - f1: 1.8865 - val_loss: 0.6673 - val_accuracy: 0.7600 - val_f1: 2.2153
Epoch 14/30
87/87 - 29s - loss: 0.4477 - accuracy: 0.8428 - f1: 1.8359 - val_loss: 0.7741 - val_accuracy: 0.7582 - val_f1: 1.8877
Epoch 15/30
87/87 - 29s - loss: 0.4980 - accuracy: 0.8262 - f1: 1.8248 - val_loss: 0.6775 - val_accuracy: 0.7745 - val_f1: 2.0269
Epoch 16/30
87/87 - 29s - loss: 0.4663 - accuracy: 0.8407 - f1: 1.8322 - val_loss: 0.7000 - val_accuracy: 0.7582 - val_f1: 1.9019
Epoch 17/30
87/87 - 29s - loss: 0.4164 - accuracy: 0.8527 - f1: 1.7481 - val_loss: 0.6603 - val_accuracy: 0.7818 - val_f1: 1.9151
Epoch 18/30
87/87 - 29s - loss: 0.4421 - accuracy: 0.8534 - f1: 1.7698 - val_loss: 0.7221 - val_accuracy: 0.7582 - val_f1: 1.9160
Epoch 19/30
87/87 - 29s - loss: 0.4147 - accuracy: 0.8544 - f1: 1.7363 - val_loss: 0.7978 - val_accuracy: 0.7564 - val_f1: 1.8716
Epoch 20/30
87/87 - 29s - loss: 0.4125 - accuracy: 0.8637 - f1: 1.7364 - val_loss: 0.6161 - val_accuracy: 0.7873 - val_f1: 1.8310
Epoch 21/30
87/87 - 29s - loss: 0.4195 - accuracy: 0.8657 - f1: 1.7871 - val_loss: 0.6296 - val_accuracy: 0.7873 - val_f1: 1.8803
Epoch 22/30
87/87 - 29s - loss: 0.4191 - accuracy: 0.8645 - f1: 1.7421 - val_loss: 0.6674 - val_accuracy: 0.7582 - val_f1: 1.9056
Epoch 23/30
87/87 - 29s - loss: 0.3869 - accuracy: 0.8652 - f1: 1.6607 - val_loss: 0.6675 - val_accuracy: 0.7727 - val_f1: 1.8695
Epoch 24/30
87/87 - 29s - loss: 0.3731 - accuracy: 0.8803 - f1: 1.6636 - val_loss: 0.7313 - val_accuracy: 0.7673 - val_f1: 1.7764
Epoch 25/30
87/87 - 29s - loss: 0.3768 - accuracy: 0.8724 - f1: 1.6316 - val_loss: 0.6881 - val_accuracy: 0.7727 - val_f1: 1.8105
Epoch 26/30
87/87 - 29s - loss: 0.3828 - accuracy: 0.8714 - f1: 1.6892 - val_loss: 0.7371 - val_accuracy: 0.7745 - val_f1: 1.7108
Epoch 27/30
87/87 - 29s - loss: 0.3373 - accuracy: 0.8858 - f1: 1.5587 - val_loss: 0.7246 - val_accuracy: 0.7564 - val_f1: 1.7966
Epoch 28/30
87/87 - 29s - loss: 0.3103 - accuracy: 0.8919 - f1: 1.6118 - val_loss: 0.7080 - val_accuracy: 0.7509 - val_f1: 1.7087
Epoch 29/30
87/87 - 29s - loss: 0.3477 - accuracy: 0.8757 - f1: 1.6038 - val_loss: 0.6606 - val_accuracy: 0.7873 - val_f1: 1.7685
Epoch 30/30
87/87 - 29s - loss: 0.3584 - accuracy: 0.8789 - f1: 1.5962 - val_loss: 0.7178 - val_accuracy: 0.7455 - val_f1: 1.7794
In [56]:
plot_history_scores(
    dict_history = history_xcept, 
    first_score = "accuracy", 
    second_score = "f1")

ResNet 50

In [57]:
from tensorflow.keras.applications import ResNet50
In [58]:
K.clear_session()
resnet_model = ResNet50(
    weights='imagenet',
    include_top=False, 
    pooling='avg',
    input_shape=(299,299,3))

# Dont retrain layers
for rn_layer in resnet_model.layers:
    rn_layer.trainable = False
In [59]:
# Add new fully-connected layers
rn_base_output = resnet_model.output
rn_base_output = Dense(128, activation='relu')(rn_base_output)
rn_base_output = Dropout(0.5)(rn_base_output)
# Output : new classifier
rn_predictions = Dense(num_breeds, activation='softmax')(rn_base_output)
In [60]:
# Define new model
my_resnet_model = Model(inputs=resnet_model.input,
                        outputs=rn_predictions)
my_resnet_model.compile(optimizer="adam",
                       loss="sparse_categorical_crossentropy",
                       metrics=["accuracy", f1])
In [61]:
# Data generator on train set with Data Augmentation
# and preprocess_input Resnet
# Validation set is define here
rn_train_datagen = ImageDataGenerator(
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest',
    validation_split=0.2,
    preprocessing_function=tf.keras.applications.resnet.preprocess_input)

#For validation and test, just rescale
rn_test_datagen = ImageDataGenerator(
    preprocessing_function=tf.keras.applications.resnet.preprocess_input)
In [62]:
history_resnet = my_resnet_model.fit(
    rn_train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='training'),
    validation_data=rn_train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='validation'),
    steps_per_epoch=int(np.ceil(x_train.shape[0] / (2*BATCH_SIZE))),
    epochs=EPOCHS,
    verbose=2)
Epoch 1/30
87/87 - 30s - loss: 2.8378 - accuracy: 0.1485 - f1: 13.2096 - val_loss: 2.4625 - val_accuracy: 0.2564 - val_f1: 11.7781
Epoch 2/30
87/87 - 29s - loss: 2.5158 - accuracy: 0.2069 - f1: 11.5054 - val_loss: 2.2628 - val_accuracy: 0.2673 - val_f1: 10.3570
Epoch 3/30
87/87 - 29s - loss: 2.2323 - accuracy: 0.2913 - f1: 9.8783 - val_loss: 1.8025 - val_accuracy: 0.4782 - val_f1: 9.0509
Epoch 4/30
87/87 - 29s - loss: 1.9948 - accuracy: 0.3634 - f1: 8.2847 - val_loss: 1.6916 - val_accuracy: 0.5273 - val_f1: 8.8773
Epoch 5/30
87/87 - 29s - loss: 1.9201 - accuracy: 0.3843 - f1: 7.7798 - val_loss: 1.5727 - val_accuracy: 0.5582 - val_f1: 7.6370
Epoch 6/30
87/87 - 29s - loss: 1.7903 - accuracy: 0.4195 - f1: 7.0191 - val_loss: 1.4221 - val_accuracy: 0.5836 - val_f1: 6.9802
Epoch 7/30
87/87 - 29s - loss: 1.6957 - accuracy: 0.4405 - f1: 6.5923 - val_loss: 1.3516 - val_accuracy: 0.5964 - val_f1: 6.7358
Epoch 8/30
87/87 - 29s - loss: 1.6307 - accuracy: 0.4621 - f1: 6.2404 - val_loss: 1.2981 - val_accuracy: 0.6109 - val_f1: 6.5782
Epoch 9/30
87/87 - 29s - loss: 1.5607 - accuracy: 0.4802 - f1: 5.8457 - val_loss: 1.2572 - val_accuracy: 0.6273 - val_f1: 5.9507
Epoch 10/30
87/87 - 29s - loss: 1.5664 - accuracy: 0.4713 - f1: 5.8664 - val_loss: 1.2277 - val_accuracy: 0.6327 - val_f1: 5.8602
Epoch 11/30
87/87 - 29s - loss: 1.4932 - accuracy: 0.5205 - f1: 5.6659 - val_loss: 1.1666 - val_accuracy: 0.6309 - val_f1: 5.6092
Epoch 12/30
87/87 - 29s - loss: 1.4454 - accuracy: 0.5126 - f1: 5.2330 - val_loss: 1.1012 - val_accuracy: 0.6291 - val_f1: 4.6703
Epoch 13/30
87/87 - 29s - loss: 1.4268 - accuracy: 0.5198 - f1: 5.3550 - val_loss: 1.1480 - val_accuracy: 0.6455 - val_f1: 4.7537
Epoch 14/30
87/87 - 29s - loss: 1.4407 - accuracy: 0.5129 - f1: 4.9863 - val_loss: 1.0328 - val_accuracy: 0.6836 - val_f1: 4.4283
Epoch 15/30
87/87 - 29s - loss: 1.3813 - accuracy: 0.5424 - f1: 5.0455 - val_loss: 1.0899 - val_accuracy: 0.6745 - val_f1: 4.6639
Epoch 16/30
87/87 - 29s - loss: 1.3680 - accuracy: 0.5273 - f1: 4.9400 - val_loss: 1.0877 - val_accuracy: 0.6455 - val_f1: 4.5989
Epoch 17/30
87/87 - 29s - loss: 1.3616 - accuracy: 0.5494 - f1: 4.8397 - val_loss: 1.0970 - val_accuracy: 0.6473 - val_f1: 4.6664
Epoch 18/30
87/87 - 29s - loss: 1.3289 - accuracy: 0.5451 - f1: 4.6420 - val_loss: 1.0770 - val_accuracy: 0.6818 - val_f1: 5.0217
Epoch 19/30
87/87 - 29s - loss: 1.3457 - accuracy: 0.5458 - f1: 4.7087 - val_loss: 1.0076 - val_accuracy: 0.6582 - val_f1: 4.3429
Epoch 20/30
87/87 - 29s - loss: 1.2925 - accuracy: 0.5689 - f1: 4.5985 - val_loss: 1.0749 - val_accuracy: 0.6473 - val_f1: 4.3279
Epoch 21/30
87/87 - 29s - loss: 1.2667 - accuracy: 0.5544 - f1: 4.5744 - val_loss: 0.9594 - val_accuracy: 0.6764 - val_f1: 4.1011
Epoch 22/30
87/87 - 29s - loss: 1.3126 - accuracy: 0.5573 - f1: 4.5831 - val_loss: 0.9764 - val_accuracy: 0.6891 - val_f1: 4.3330
Epoch 23/30
87/87 - 29s - loss: 1.2391 - accuracy: 0.5746 - f1: 4.2611 - val_loss: 1.0294 - val_accuracy: 0.6400 - val_f1: 4.2188
Epoch 24/30
87/87 - 29s - loss: 1.1827 - accuracy: 0.5999 - f1: 4.3076 - val_loss: 0.8886 - val_accuracy: 0.6891 - val_f1: 3.4889
Epoch 25/30
87/87 - 29s - loss: 1.1699 - accuracy: 0.5876 - f1: 4.0386 - val_loss: 1.0175 - val_accuracy: 0.6455 - val_f1: 3.6557
Epoch 26/30
87/87 - 29s - loss: 1.2477 - accuracy: 0.5573 - f1: 4.3528 - val_loss: 0.9266 - val_accuracy: 0.7018 - val_f1: 3.8245
Epoch 27/30
87/87 - 29s - loss: 1.2059 - accuracy: 0.5769 - f1: 4.1425 - val_loss: 0.9444 - val_accuracy: 0.6764 - val_f1: 3.4783
Epoch 28/30
87/87 - 29s - loss: 1.1914 - accuracy: 0.5826 - f1: 4.2077 - val_loss: 0.9575 - val_accuracy: 0.6873 - val_f1: 3.5320
Epoch 29/30
87/87 - 29s - loss: 1.1653 - accuracy: 0.5768 - f1: 4.0557 - val_loss: 0.9754 - val_accuracy: 0.6527 - val_f1: 3.6107
Epoch 30/30
87/87 - 29s - loss: 1.1666 - accuracy: 0.5919 - f1: 4.1215 - val_loss: 0.9605 - val_accuracy: 0.6800 - val_f1: 3.6854
In [63]:
plot_history_scores(
    dict_history = history_resnet, 
    first_score = "accuracy", 
    second_score = "f1")
In [64]:
with plt.style.context('seaborn-whitegrid'):
    plt.figure(figsize=(13,10))
    plt.plot(history.history['val_accuracy'],
             label='Custom CNN')
    plt.plot(history_custom_cnn.history['val_accuracy'],
             label='Hypt custom CNN - Mean accuracy: {:.2f}'.format(
                 np.mean(history_custom_cnn.history['val_accuracy'])))
    plt.plot(history_xcept.history['val_accuracy'],
             label='Xception - Mean accuracy: {:.2f}'.format(
                 np.mean(history_xcept.history['val_accuracy'])))
    plt.plot(history_resnet.history['val_accuracy'],
             label='Resnet50 - Mean accuracy: {:.2f}'.format(
                 np.mean(history_resnet.history['val_accuracy'])))
    plt.plot(history_vgg16.history['val_accuracy'],
             label='VGG-16 - Mean accuracy: {:.2f}'.format(
                 np.mean(history_vgg16.history['val_accuracy'])))
    plt.title('Accuracy of differents ConvNet tested over epochs',
              fontsize=18)
    plt.ylabel('Accuracy')
    plt.xlabel('epoch')
    plt.legend(loc='upper left')
    plt.show()

Fine tuning hyperparameters for Xception

We decided to keep the Xception model for the rest of this project as it gives the best performance on our chosen metrics

Finetuning the Fully connected layers

We will use kerastuner to fine tune the connected layer we added to Xception

In [65]:
def model_builder(hp):
    # Load base model
    xception_model = tf.keras.applications.xception.Xception(
        weights='imagenet',
        include_top=False,
        pooling='avg',
        input_shape=(299,299,3))
    
    for layer in xception_model.layers:
        layer.trainable = False
    
    base_output = xception_model.output
    
    # Tune dense units
    hp_units = hp.Int('dense_units',
                      min_value=32,
                      max_value=300,
                      step=32,
                      default=128)

    base_output = Dense(units=hp_units, 
                        activation='relu')(base_output)
    
    base_output = Dropout(0.5)(base_output)
    
    # Output : new classifier
    predictions = Dense(num_breeds, activation='softmax')(base_output)

    # Define new model
    my_xcept_model = Model(inputs=xception_model.input,
                       outputs=predictions)
    
    # Tune learning rate
    hp_learning_rate = hp.Choice(
        name='learning_rate',
        values=[1e-2, 1e-3, 1e-4])
    
    hp_beta1 = hp.Choice(
        name='beta_1', 
        values=[0.9,0.95,0.99])

    my_xcept_model.compile(
        optimizer=keras.optimizers.Adam(learning_rate=hp_learning_rate, beta_1=hp_beta1),
        loss="sparse_categorical_crossentropy",
        metrics=["accuracy", f1])
    
    return my_xcept_model
In [67]:
# Tune the learning rate for the optimizer
# Constuct the tuner of kerastuner
tuner = kt.RandomSearch(
    model_builder, 
    objective='val_accuracy',
    max_trials=5,
    directory='my_dir',
    overwrite=True,
    project_name='Xcept_kt'
    )

# Define a early stopping
stop_early = tf.keras.callbacks.EarlyStopping(
    monitor='val_accuracy',
    patience=5)

# Search best params
tuner.search(
    train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='training'),
    validation_data=train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='validation'),
    epochs=20,
    callbacks=[stop_early])

# Get the optimal hyperparameters
best_hps = tuner.get_best_hyperparameters(num_trials=1)[0]

print("-" * 50)
print("Xception Hyperparameters optimization :")
print("-" * 50)
print(f"""
Best learning rate : {best_hps.get('learning_rate')}.\n
Best Dense units : {best_hps.get('dense_units')}.\n
Best beta_1 : {best_hps.get('beta_1')}.
""")
Trial 5 Complete [00h 07m 04s]
val_accuracy: 0.7854545712471008

Best val_accuracy So Far: 0.7927272915840149
Total elapsed time: 00h 48m 40s
INFO:tensorflow:Oracle triggered exit
INFO:tensorflow:Oracle triggered exit
--------------------------------------------------
Xception Hyperparameters optimization :
--------------------------------------------------

Best learning rate : 0.001.

Best Dense units : 128.

Best beta_1 : 0.95.

Now that we have the optimal parameters, we can now retrain the model to have the fully connected layer optimised

In [68]:
hypermodel = tuner.hypermodel.build(best_hps)
hypermodel.fit(
    train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='training'), 
    epochs=EPOCHS,
    validation_data=train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        subset='validation'),
    verbose=2)
hypermodel.save('xception_hypermodel.h5')
print("Model saved")
Epoch 1/30
138/138 - 42s - loss: 1.9371 - accuracy: 0.4462 - f1: 8.5733 - val_loss: 1.1009 - val_accuracy: 0.6982 - val_f1: 4.9230
Epoch 2/30
138/138 - 41s - loss: 1.1373 - accuracy: 0.6577 - f1: 4.0719 - val_loss: 0.8111 - val_accuracy: 0.7400 - val_f1: 3.1619
Epoch 3/30
138/138 - 41s - loss: 1.0023 - accuracy: 0.6818 - f1: 3.3819 - val_loss: 0.7857 - val_accuracy: 0.7418 - val_f1: 2.9735
Epoch 4/30
138/138 - 41s - loss: 0.9129 - accuracy: 0.7140 - f1: 3.0138 - val_loss: 0.6944 - val_accuracy: 0.7436 - val_f1: 2.6192
Epoch 5/30
138/138 - 41s - loss: 0.8320 - accuracy: 0.7335 - f1: 2.7446 - val_loss: 0.7208 - val_accuracy: 0.7618 - val_f1: 2.8167
Epoch 6/30
138/138 - 41s - loss: 0.7864 - accuracy: 0.7463 - f1: 2.7840 - val_loss: 0.7100 - val_accuracy: 0.7509 - val_f1: 2.4672
Epoch 7/30
138/138 - 41s - loss: 0.7383 - accuracy: 0.7581 - f1: 2.5194 - val_loss: 0.7044 - val_accuracy: 0.7527 - val_f1: 2.4069
Epoch 8/30
138/138 - 41s - loss: 0.7523 - accuracy: 0.7631 - f1: 2.5563 - val_loss: 0.7006 - val_accuracy: 0.7473 - val_f1: 2.5613
Epoch 9/30
138/138 - 41s - loss: 0.7282 - accuracy: 0.7671 - f1: 2.4618 - val_loss: 0.6604 - val_accuracy: 0.7782 - val_f1: 2.2877
Epoch 10/30
138/138 - 41s - loss: 0.6875 - accuracy: 0.7753 - f1: 2.3864 - val_loss: 0.6782 - val_accuracy: 0.7818 - val_f1: 2.3098
Epoch 11/30
138/138 - 41s - loss: 0.6646 - accuracy: 0.7749 - f1: 2.3371 - val_loss: 0.6711 - val_accuracy: 0.7691 - val_f1: 2.2507
Epoch 12/30
138/138 - 41s - loss: 0.6467 - accuracy: 0.7889 - f1: 2.2609 - val_loss: 0.6888 - val_accuracy: 0.7618 - val_f1: 2.3975
Epoch 13/30
138/138 - 41s - loss: 0.6639 - accuracy: 0.7776 - f1: 2.3793 - val_loss: 0.6708 - val_accuracy: 0.7582 - val_f1: 2.1493
Epoch 14/30
138/138 - 41s - loss: 0.6150 - accuracy: 0.7948 - f1: 2.1864 - val_loss: 0.6369 - val_accuracy: 0.7745 - val_f1: 2.0574
Epoch 15/30
138/138 - 41s - loss: 0.6141 - accuracy: 0.7935 - f1: 2.1766 - val_loss: 0.6594 - val_accuracy: 0.7764 - val_f1: 2.0091
Epoch 16/30
138/138 - 41s - loss: 0.6149 - accuracy: 0.7930 - f1: 2.2231 - val_loss: 0.6839 - val_accuracy: 0.7418 - val_f1: 2.1707
Epoch 17/30
138/138 - 41s - loss: 0.6263 - accuracy: 0.7826 - f1: 2.2285 - val_loss: 0.6628 - val_accuracy: 0.7673 - val_f1: 2.1581
Epoch 18/30
138/138 - 41s - loss: 0.5401 - accuracy: 0.8162 - f1: 2.0448 - val_loss: 0.6456 - val_accuracy: 0.7564 - val_f1: 2.0105
Epoch 19/30
138/138 - 41s - loss: 0.5774 - accuracy: 0.8057 - f1: 2.0839 - val_loss: 0.6566 - val_accuracy: 0.7636 - val_f1: 2.1047
Epoch 20/30
138/138 - 41s - loss: 0.5544 - accuracy: 0.8139 - f1: 2.0518 - val_loss: 0.6563 - val_accuracy: 0.7691 - val_f1: 1.9172
Epoch 21/30
138/138 - 41s - loss: 0.5291 - accuracy: 0.8125 - f1: 2.0048 - val_loss: 0.6518 - val_accuracy: 0.7691 - val_f1: 1.9042
Epoch 22/30
138/138 - 41s - loss: 0.5451 - accuracy: 0.8148 - f1: 1.9794 - val_loss: 0.6496 - val_accuracy: 0.7782 - val_f1: 1.9872
Epoch 23/30
138/138 - 41s - loss: 0.5365 - accuracy: 0.8171 - f1: 1.9598 - val_loss: 0.6650 - val_accuracy: 0.7564 - val_f1: 1.7952
Epoch 24/30
138/138 - 41s - loss: 0.5388 - accuracy: 0.8084 - f1: 1.9836 - val_loss: 0.6214 - val_accuracy: 0.7964 - val_f1: 1.9607
Epoch 25/30
138/138 - 41s - loss: 0.5385 - accuracy: 0.8130 - f1: 1.9916 - val_loss: 0.6994 - val_accuracy: 0.7455 - val_f1: 1.9993
Epoch 26/30
138/138 - 41s - loss: 0.4919 - accuracy: 0.8339 - f1: 1.9009 - val_loss: 0.7035 - val_accuracy: 0.7564 - val_f1: 1.9399
Epoch 27/30
138/138 - 41s - loss: 0.5513 - accuracy: 0.8134 - f1: 1.9180 - val_loss: 0.6656 - val_accuracy: 0.7836 - val_f1: 2.0627
Epoch 28/30
138/138 - 41s - loss: 0.5281 - accuracy: 0.8225 - f1: 1.9885 - val_loss: 0.7258 - val_accuracy: 0.7673 - val_f1: 1.9457
Epoch 29/30
138/138 - 41s - loss: 0.5117 - accuracy: 0.8252 - f1: 1.9713 - val_loss: 0.6787 - val_accuracy: 0.7909 - val_f1: 1.8688
Epoch 30/30
138/138 - 41s - loss: 0.4995 - accuracy: 0.8261 - f1: 1.8924 - val_loss: 0.6373 - val_accuracy: 0.7800 - val_f1: 1.8290
Model saved

Finetuning blocks inside Xception

Remember at this point we only optimised the layers "outside" of Xception. Hence now we would like to re-train only some parts of the blocks of Xception

Xception has 3 flows:

  • Entry flow
  • Middle flow
  • Exit flow

We are only going to retrain the exit flow with the previous newly optimised fully connected layer parameters. That is the reason why we only unfrezze the layers after the 115th layer

image.png

In [69]:
def xception_fine_tune(nb_layers):
    """
    Raison d'être: Training some parts only of model and returning the trained model
    Args: 
        nb_layer: number of layers NOT to be trained
    Returns:
        hypermodel_t: the newly trained model
    """
    # Load the pre trained model
    hypermodel_t = load_model('./xception_hypermodel.h5', custom_objects={"f1": f1})
    
    # re train the last layers
    for i, layer in enumerate(hypermodel_t.layers):
        if i < nb_layers:
            layer.trainable = False
        else:
            layer.trainable = True
            
    # Compile model
    hypermodel_t.compile(
        optimizer='adam',
        loss="sparse_categorical_crossentropy",
        metrics=["accuracy", f1])
    
    return hypermodel_t
In [70]:
# Define a early stopping
stop_early = tf.keras.callbacks.EarlyStopping(
    monitor='val_accuracy',
    patience=5)

# Dont train the 115 first layers. Last layer excluding the exit flow is layer 115. Then we get in the exit flow. 
my_tuned_xcept_model = xception_fine_tune(115)
fine_tuned_history = my_tuned_xcept_model.fit(
    train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        shuffle=False,
        subset='training'), 
    epochs=EPOCHS,
    validation_data=train_datagen.flow(
        x_train, y_train,
        batch_size=BATCH_SIZE,
        shuffle=False,
        subset='validation'),
    callbacks=[stop_early],
    verbose=2)

my_tuned_xcept_model.save('my_tuned_xcept_model.h5')
print("Tuned Model saved")
Epoch 1/30
138/138 - 42s - loss: 1.1300 - accuracy: 0.6686 - f1: 3.2206 - val_loss: 1.0827 - val_accuracy: 0.6855 - val_f1: 1.9214
Epoch 2/30
138/138 - 42s - loss: 0.9153 - accuracy: 0.7177 - f1: 2.5954 - val_loss: 0.8688 - val_accuracy: 0.7400 - val_f1: 1.8888
Epoch 3/30
138/138 - 42s - loss: 0.7203 - accuracy: 0.7771 - f1: 2.2644 - val_loss: 0.8232 - val_accuracy: 0.7400 - val_f1: 2.0068
Epoch 4/30
138/138 - 41s - loss: 0.6238 - accuracy: 0.8062 - f1: 2.0660 - val_loss: 1.1217 - val_accuracy: 0.7218 - val_f1: 1.6727
Epoch 5/30
138/138 - 42s - loss: 0.5417 - accuracy: 0.8298 - f1: 1.8583 - val_loss: 1.0613 - val_accuracy: 0.7600 - val_f1: 1.5788
Epoch 6/30
138/138 - 42s - loss: 0.4713 - accuracy: 0.8466 - f1: 1.7480 - val_loss: 1.3419 - val_accuracy: 0.7218 - val_f1: 1.6297
Epoch 7/30
138/138 - 42s - loss: 0.4530 - accuracy: 0.8584 - f1: 1.7060 - val_loss: 0.6916 - val_accuracy: 0.8055 - val_f1: 1.5642
Epoch 8/30
138/138 - 42s - loss: 0.3869 - accuracy: 0.8747 - f1: 1.5591 - val_loss: 0.9007 - val_accuracy: 0.7709 - val_f1: 1.5952
Epoch 9/30
138/138 - 42s - loss: 0.4197 - accuracy: 0.8693 - f1: 1.6237 - val_loss: 1.1154 - val_accuracy: 0.7309 - val_f1: 1.5430
Epoch 10/30
138/138 - 42s - loss: 0.3999 - accuracy: 0.8729 - f1: 1.5314 - val_loss: 0.9997 - val_accuracy: 0.7345 - val_f1: 1.7005
Epoch 11/30
138/138 - 42s - loss: 0.3782 - accuracy: 0.8770 - f1: 1.5804 - val_loss: 0.9540 - val_accuracy: 0.7382 - val_f1: 1.6054
Epoch 12/30
138/138 - 42s - loss: 0.3019 - accuracy: 0.9069 - f1: 1.4106 - val_loss: 0.8820 - val_accuracy: 0.7836 - val_f1: 1.4051
Tuned Model saved
In [71]:
plot_history_scores(
    dict_history = fine_tuned_history, 
    first_score = "accuracy", 
    second_score = "f1")
In [72]:
with plt.style.context('seaborn-whitegrid'):
    plt.figure(figsize=(13,10))
    plt.plot(history.history['val_accuracy'],
             label='CNN - Mean accuracy: {:.2f}'.format(
                 np.mean(history.history['val_accuracy'])))
    plt.plot(history_custom_cnn.history['val_accuracy'],
             label='Hypt custom CNN - Mean accuracy: {:.2f}'.format(
                 np.mean(history_custom_cnn.history['val_accuracy'])))
    plt.plot(history_xcept.history['val_accuracy'],
             label='Xception - Mean accuracy: {:.2f}'.format(
                 np.mean(history_xcept.history['val_accuracy'])))
    plt.plot(history_resnet.history['val_accuracy'],
             label='Resnet50 - Mean accuracy: {:.2f}'.format(
                 np.mean(history_resnet.history['val_accuracy'])))
    plt.plot(history_vgg16.history['val_accuracy'],
             label='VGG-16 - Mean accuracy: {:.2f}'.format(
                 np.mean(history_vgg16.history['val_accuracy'])))
    plt.plot(fine_tuned_history.history['val_accuracy'],
             label='Fine-tuned Xception - Mean accuracy: {:.2f}'.format(
                 np.mean(fine_tuned_history.history['val_accuracy'])))
    plt.title('Accuracy of differents ConvNet tested over epochs',
              fontsize=18)
    plt.ylabel('Validation accuracy')
    plt.xlabel('epoch')
    plt.legend(loc='upper left')
    plt.show()

Testing our finetuned model on Test set

In [73]:
# Model evaluation on test set
xception_eval = fine_tuned_history.model.evaluate(
    test_datagen.flow(
        x_test, y_test,
        batch_size=BATCH_SIZE,
        shuffle=False),
    verbose=1)
print("-" * 50)
print("Xception model evaluation :")
print("-" * 50)
print('Test Loss: {:.3f}'.format(xception_eval[0]))
print('Test Accuracy: {:.3f}'.format(xception_eval[1]))
print('Test F1 score: {:.3f}'.format(xception_eval[2]))
44/44 [==============================] - 5s 104ms/step - loss: 0.7087 - accuracy: 0.8113 - f1: 1.3537
--------------------------------------------------
Xception model evaluation :
--------------------------------------------------
Test Loss: 0.709
Test Accuracy: 0.811
Test F1 score: 1.354
In [74]:
# Make predictions
Y_pred = fine_tuned_history.model.predict(
    test_datagen.flow(
        x_test, y_test,
        batch_size=BATCH_SIZE,
        shuffle=False))
y_pred = np.argmax(Y_pred, axis=1)

# Inverse transform of encoding
y_pred_s = encoder.inverse_transform(y_pred)
y_test_s = encoder.inverse_transform(y_test)

# Confusion Matrix
cf_matrix = confusion_matrix(y_test, y_pred)

fig = plt.figure(figsize=(12,10))
ax = sns.heatmap(cf_matrix, annot=True)
ax.set_xlabel("PREDICTED LABELS", color="g")
ax.set_ylabel("TRUE LABELS", color="orange")
ax.xaxis.set_ticklabels(encoder.classes_, 
                        rotation='vertical')
ax.yaxis.set_ticklabels(encoder.classes_,
                        rotation='horizontal')
plt.title("Confusion Matrix on Xception predicted results\n",
          fontsize=18)
plt.show()
In [75]:
# Classification report
print(classification_report(
    y_test, y_pred, 
    target_names=sorted(set(y_test_s))))
                            precision    recall  f1-score   support

              Afghan_hound       0.85      0.98      0.91        42
        Australian_terrier       0.93      0.90      0.92        30
             Border_collie       0.82      1.00      0.90        37
                  Doberman       0.95      0.64      0.76        33
            English_setter       0.92      0.58      0.71        38
                Eskimo_dog       0.51      0.54      0.53        37
            French_bulldog       1.00      0.87      0.93        53
           German_shepherd       0.69      0.90      0.78        20
             Gordon_setter       0.90      0.90      0.90        29
            Great_Pyrenees       0.53      0.98      0.69        45
Greater_Swiss_Mountain_dog       1.00      0.79      0.89        34
                  Leonberg       0.98      0.85      0.91        48
                Rottweiler       0.92      0.89      0.90        37
                      Shih       1.00      0.83      0.91        53
            Siberian_husky       0.65      0.49      0.56        45
 Staffordshire_bullterrier       0.73      0.86      0.79        28
              bull_mastiff       0.68      0.96      0.79        26
            cocker_spaniel       0.76      0.57      0.65        23
                  komondor       1.00      0.90      0.95        31

                  accuracy                           0.81       689
                 macro avg       0.83      0.81      0.81       689
              weighted avg       0.84      0.81      0.81       689

In [76]:
fig = plt.figure(1, figsize=(20,20))
fig.patch.set_facecolor('#343434')
plt.suptitle("Predicted VS actual for Xception model fine-tuned",
             y=.92, fontsize=22,
             color="white")

n = 0

for i in range(12):
    n+=1
    r = int(np.random.randint(0, x_test.shape[0], 1))
    plt.subplot(3,4,n)
    plt.subplots_adjust(hspace = 0.1, wspace = 0.1)
    plt.imshow(image.array_to_img(x_test[r]))
    plt.title('Actual = {}\nPredicted = {}'.format(y_test_s[r] , y_pred_s[r]),
              color="white")
    plt.xticks([]) , plt.yticks([])
    
plt.show()
In [ ]: